美文网首页自动化
system-rules捕获被catch的异常

system-rules捕获被catch的异常

作者: 佛系小懒 | 来源:发表于2020-02-06 18:51 被阅读0次

    断言,对于在方法层面已经被捕获的一场,没法通过单元测试再次捕获异常,可以通过sys-rules对控制台的ERROR、OUT信息进行捕获,从而进行断言

    System Rules is a collection of JUnit rules for testing code which uses  `java.lang.System`.

    # System Rules

    Linux(https://travis-ci.org/stefanbirkner/system-rules.svg?branch=master)](https://travis-ci.org/stefanbirkner/system-rules)

    Windows(https://ci.appveyor.com/api/projects/status/vr0c93rssc6mhetl/branch/master?svg=true)](https://ci.appveyor.com/project/stefanbirkner/system-rules)

    mvn依赖

    <dependency>

    <groupId>com.github.stefanbirkner</groupId>

    <artifactId>system-rules</artifactId>

    <version>1.18.0<version>

    </dependency>

    Please don't forget to add the scope `test` if you're using System Rules for tests only.

    具体的使用参见UnitTest中TestException 类及AcceptanceTestRunner类

    package com.XXX.XXXX;

    import org.junit.AfterClass;

    import org.junit.BeforeClass;

    import org.junit.ClassRule;

    import org.junit.Ignore;

    import org.junit.internal.AssumptionViolatedException;

    import org.junit.internal.runners.model.EachTestNotifier;

    import org.junit.internal.runners.statements.RunAfters;

    import org.junit.internal.runners.statements.RunBefores;

    import org.junit.rules.RunRules;

    import org.junit.rules.TestRule;

    import org.junit.runner.Description;

    import org.junit.runner.notification.Failure;

    import org.junit.runner.notification.RunNotifier;

    import org.junit.runners.BlockJUnit4ClassRunner;

    import org.junit.runners.model.FrameworkMethod;

    import org.junit.runners.model.InitializationError;

    import org.junit.runners.model.Statement;

    import org.junit.runners.model.TestClass;

    import java.lang.reflect.InvocationTargetException;

    import java.lang.reflect.Method;

    import java.util.Collection;

    import java.util.List;

    import static java.util.Collections.emptyList;

    import static java.util.Collections.singleton;

    public class AcceptanceTestRunner extends BlockJUnit4ClassRunner {

    private static final Collection<Failure> NO_FAILURES = emptyList();

    private final Method expectFailure;

    private final Method verifyStateAfterTest;

    private final Method verifyResult;

    private final TestClass testClass;

    public AcceptanceTestRunner(Class<?> testClass) throws InitializationError {

    super(extractInnerTestClass(testClass));

    expectFailure = extractMethod(testClass, "expectFailure", Failure.class);

    verifyResult = extractMethod(testClass, "verifyResult", Collection.class);

    verifyStateAfterTest = extractMethod(testClass, "verifyStateAfterTest");

    this.testClass = new TestClass(testClass);

    verifyCheckPresent();

    }

    private static Class<?> extractInnerTestClass(Class<?> testClass)

    throws InitializationError {

    Class<?>[] innerClasses = testClass.getClasses();

    if (innerClasses.length > 1)

    throw new InitializationError("The class " + testClass

    + " has " + innerClasses.length + " inner classes, but only"

    + " one inner class with name TestClass is expected.");

    else if (innerClasses.length == 0

    || !innerClasses[0].getSimpleName().equals("TestClass"))

    throw new InitializationError("The class " + testClass

    + " has no inner class with name TestClass.");

    else

    return innerClasses[0];

    }

    private void verifyCheckPresent() {

    boolean noCheck = expectFailure == null

    && verifyResult == null

    && verifyStateAfterTest == null;

    if (noCheck)

    throw new IllegalStateException(

    "No expectation is defined for the " + getName()

    + ". It needs either a method expectFailure, verifyResult or verifyStateAfterTest.");

    }

    private static Method extractMethod(Class<?> testClass, String name, Class<?>... parameterTypes) {

    try {

    return testClass.getMethod(name, parameterTypes);

    } catch (NoSuchMethodException e) {

    return null;

    }

    }

    @Override

    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {

    Description description = describeChild(method);

    if (method.getAnnotation(Ignore.class) != null)

    notifier.fireTestIgnored(description);

    else

    runTest(methodBlock(method), description, notifier);

    }

    protected Statement classBlock(final RunNotifier notifier) {

    Statement statement = super.classBlock(notifier);

    statement = withBeforeClasses(statement);

    statement = withAfterClasses(statement);

    statement = withClassRules(statement);

    return statement;

    }

    protected Statement withBeforeClasses(Statement statement) {

    List<FrameworkMethod> befores = testClass

    .getAnnotatedMethods(BeforeClass.class);

    return befores.isEmpty() ? statement :

    new RunBefores(statement, befores, null);

    }

    protected Statement withAfterClasses(Statement statement) {

    List<FrameworkMethod> afters = testClass

    .getAnnotatedMethods(AfterClass.class);

    return afters.isEmpty() ? statement :

    new RunAfters(statement, afters, null);

    }

    private Statement withClassRules(Statement statement) {

    List<TestRule> classRules = classRules();

    return classRules.isEmpty() ? statement :

    new RunRules(statement, classRules, getDescription());

    }

    protected List<TestRule> classRules() {

    return testClass.getAnnotatedFieldValues(

    null, ClassRule.class, TestRule.class);

    }

    private void runTest(Statement statement, Description description,

                            RunNotifier notifier) {

    EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);

    eachNotifier.fireTestStarted();

    try {

    statement.evaluate();

    handleNoFailure(eachNotifier);

    } catch (AssumptionViolatedException e) {

    handleFailedAssumption(description, eachNotifier, e);

    } catch (Throwable e) {

    handleException(description, eachNotifier, e);

    } finally {

    invokeIfPresent(verifyStateAfterTest, eachNotifier);

    eachNotifier.fireTestFinished();

    }

    }

    private void handleNoFailure(EachTestNotifier eachNotifier) {

    if (expectFailure != null)

    eachNotifier.addFailure(new AssertionError("Test did not fail."));

    invokeIfPresent(verifyResult, eachNotifier, NO_FAILURES);

    }

    private void handleFailedAssumption(Description description, EachTestNotifier eachNotifier, AssumptionViolatedException e) {

    eachNotifier.addFailedAssumption(e);

    if (expectFailure != null)

    eachNotifier.addFailure(new AssertionError("Test did not fail."));

    invokeIfPresent(

    verifyResult, eachNotifier, singleton(new Failure(description, e)));

    }

    private void handleException(Description description, EachTestNotifier eachNotifier,

                                    Throwable e) {

    invokeIfPresent(

    verifyResult, eachNotifier, singleton(new Failure(description, e)));

    invokeIfPresent(

    expectFailure, eachNotifier, new Failure(description, e));

    if (expectFailure == null && verifyResult == null)

    eachNotifier.addFailure(e);

    }

    private void invokeIfPresent(Method method, EachTestNotifier notifier, Object... args) {

    if (method != null)

    try {

    method.invoke(null, args);

    } catch (IllegalAccessException e) {

    fail(notifier, e, "Failed to invoke '" + method.getName() + "'.");

    } catch (InvocationTargetException e) {

    fail(notifier, e, "Failed to invoke '" + method.getName() + "'.");

    } catch (Exception e) {

    notifier.addFailure(e);

    }

    }

    private void fail(EachTestNotifier eachNotifier, InvocationTargetException e, String message) {

    if (e.getCause() instanceof AssertionError)

    eachNotifier.addFailure(e.getCause());

    else

    fail(eachNotifier, (Exception) e, message);

    }

    private void fail(EachTestNotifier eachNotifier, Exception e, String message) {

    AssertionError error = new AssertionError(message);

    error.initCause(e);

    eachNotifier.addFailure(error);

    }

    }

    // 在测试类里面添加如下信息

    private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

    private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();

    @Before

    public void setUpStreams() {

        System.setOut(new PrintStream(outContent));

        System.setErr(new PrintStream(errContent));

    }

    /*需要添加pom依赖

    * 需要@RunWith(AcceptanceTestRunner.class)

    * 需要使用内部类

    * 需要enableLog()

    * */

    @RunWith(AcceptanceTestRunner.class)

    public static class catch_exception_through_system_rule {

        public static class TestClass {

            @Rule

            public final SystemOutRule systemOutRule = new SystemOutRule();

            @Rule

            public final SystemErrRule systemErrRule = new SystemErrRule();

            /*记得要toString*/

            @org.junit.Test

            public void test() {

                System.out.print("text before enabling log");

                systemOutRule.enableLog();

                System.out.print("text after enabling log true\n \t \r 123456 ");

                assertTrue(systemOutRule.getLog().toString().contains("text after enabling log"));

            }

            @org.junit.Test

            public void testError() {

                System.err.print("text before enabling log");

                systemErrRule.enableLog();

                System.err.print("text after enabling log");

                assertTrue(systemErrRule.getLog().equals("text after enabling log"));

            }

        }

    }

    相关文章

      网友评论

        本文标题:system-rules捕获被catch的异常

        本文链接:https://www.haomeiwen.com/subject/ouvuxhtx.html