All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.test.AssertThrows Maven / Gradle / Ivy

There is a newer version: 6.1.13
Show newest version
/*
 * Copyright 2002-2014 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.test;

import org.springframework.util.Assert;

/**
 * {@code AssertThrows} is a simple method object that encapsulates the
 * 'test-for-exception' scenario for unit testing. Intended for
 * use with JUnit or TestNG.
 *
 * 

Given the following business class... * *

 * // the class under test
 * public class Foo {
 *    public void someBusinessLogic(String name) {
 *        if (name == null) {
 *            throw new IllegalArgumentException("The 'name' argument is required");
 *        }
 *        // rest of business logic here...
 *    }
 * }
* *

The test for the above bad argument path can be expressed using * {@code AssertThrows} like so: * *

 * public class FooTest {
 *    public void testSomeBusinessLogicBadArgumentPath() {
 *        new AssertThrows(IllegalArgumentException.class) {
 *            public void test() {
 *                new Foo().someBusinessLogic(null);
 *            }
 *        }.runTest();
 *    }
 * }
* *

This will result in the test passing if the {@code Foo.someBusinessLogic(..)} * method threw an {@code IllegalArgumentException}; if it did not, the * test would fail with the following message: * *

"Must have thrown a [class java.lang.IllegalArgumentException]"
* *

If the wrong type of {@code Throwable} was thrown, * the test will also fail, this time with a message similar to the following: * *

"java.lang.AssertionError: Was expecting a [class java.lang.UnsupportedOperationException] to be thrown, but instead a [class java.lang.IllegalArgumentException] was thrown"
* *

The test for the correct {@code Throwable} respects polymorphism, * so you can test that any old {@code Exception} is thrown like so: * *

 * public class FooTest {
 *    public void testSomeBusinessLogicBadArgumentPath() {
 *        // any Exception will do...
 *        new AssertThrows(Exception.class) {
 *            public void test() {
 *                new Foo().someBusinessLogic(null);
 *            }
 *        }.runTest();
 *    }
 * }
* * @author Rick Evans * @author Juergen Hoeller * @author Sam Brannen * @since 2.0 * @deprecated Favor use of JUnit's {@code @Test(expected=...)} or * {@code @Rule ExpectedException} support or TestNG's * {@code @Test(expectedExceptions=...)} support */ @Deprecated public abstract class AssertThrows { private final Class expectedException; private String failureMessage; private Throwable actualException; /** * Create a new instance of the {@code AssertThrows} class. * @param expectedException the {@link Throwable} expected to be * thrown during the execution of the surrounding test * @throws IllegalArgumentException if the supplied {@code expectedException} is * {@code null}; or if said argument is not a {@code Throwable}-derived class */ public AssertThrows(Class expectedException) { this(expectedException, null); } /** * Create a new instance of the {@code AssertThrows} class. * @param expectedException the {@link Throwable} expected to be * thrown during the execution of the surrounding test * @param failureMessage the extra, contextual failure message that will be * included in the failure text if the text fails (can be {@code null}) * @throws IllegalArgumentException if the supplied {@code expectedException} is * {@code null}; or if said argument is not a {@code Throwable}-derived class */ public AssertThrows(Class expectedException, String failureMessage) { Assert.notNull(expectedException, "expectedException is required"); Assert.isAssignable(Throwable.class, expectedException, "expectedException: "); this.expectedException = expectedException; this.failureMessage = failureMessage; } /** * Return the {@link java.lang.Throwable} expected to be thrown during * the execution of the surrounding test. */ protected Class getExpectedException() { return this.expectedException; } /** * Set the extra, contextual failure message that will be included * in the failure text if the text fails. */ public void setFailureMessage(String failureMessage) { this.failureMessage = failureMessage; } /** * Return the extra, contextual failure message that will be included * in the failure text if the text fails. */ protected String getFailureMessage() { return this.failureMessage; } /** * Subclass must override this {@code abstract} method and * provide the test logic. * @throws Throwable if an error occurs during the execution of the * aforementioned test logic */ public abstract void test() throws Throwable; /** * The main template method that drives the running of the * {@linkplain #test() test logic} and the * {@linkplain #checkExceptionExpectations(Throwable) checking} of the * resulting (expected) {@link java.lang.Throwable}. * @see #test() * @see #doFail() * @see #checkExceptionExpectations(Throwable) */ public void runTest() { try { test(); doFail(); } catch (Throwable actualException) { this.actualException = actualException; checkExceptionExpectations(actualException); } } /** * Template method called when the test fails; i.e. the expected * {@link java.lang.Throwable} is not thrown. *

The default implementation simply fails the test by throwing an * {@link AssertionError}. *

If you want to customize the failure message, consider overriding * {@link #createMessageForNoExceptionThrown()}, and / or supplying an * extra, contextual failure message via the appropriate constructor. * @see #getFailureMessage() * @see #createMessageForNoExceptionThrown() */ protected void doFail() { throw new AssertionError(createMessageForNoExceptionThrown()); } /** * Creates the failure message used if the test fails * (i.e. the expected exception is not thrown in the body of the test). * @return the failure message used if the test fails * @see #getFailureMessage() */ protected String createMessageForNoExceptionThrown() { StringBuilder sb = new StringBuilder(); sb.append("Should have thrown a [").append(this.getExpectedException()).append("]"); if (getFailureMessage() != null) { sb.append(": ").append(getFailureMessage()); } return sb.toString(); } /** * Does the donkey work of checking (verifying) that the * {@link Throwable} that was thrown in the body of the test is * an instance of the {@link #getExpectedException()} class (or an * instance of a subclass). *

If you want to customize the failure message, consider overriding * {@link #createMessageForWrongThrownExceptionType(Throwable)}. * @param actualException the {@link Throwable} that has been thrown * in the body of a test method (will never be {@code null}) */ protected void checkExceptionExpectations(Throwable actualException) { if (!getExpectedException().isAssignableFrom(actualException.getClass())) { AssertionError error = new AssertionError(createMessageForWrongThrownExceptionType(actualException)); error.initCause(actualException); throw error; } } /** * Creates the failure message used if the wrong type * of {@link java.lang.Throwable} is thrown in the body of the test. * @param actualException the actual exception thrown * @return the message for the given exception */ protected String createMessageForWrongThrownExceptionType(Throwable actualException) { StringBuilder sb = new StringBuilder(); sb.append("Was expecting a [").append(getExpectedException().getName()); sb.append("] to be thrown, but instead a [").append(actualException.getClass().getName()); sb.append("] was thrown."); return sb.toString(); } /** * Expose the actual exception thrown from {@link #test}, if any. * @return the actual exception, or {@code null} if none */ public final Throwable getActualException() { return this.actualException; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy