【问题标题】:Create own @Test annotation for JUnit为 JUnit 创建自己的 @Test 注解
【发布时间】:2013-11-14 15:29:03
【问题描述】:

对于一组 JUnit 4.11 测试,我创建了一个自己的注释(我们称之为@MyTest),我将其应用于一些单元测试。就目前而言,我必须用@Test@MyTest 来注释这些测试——这不是我认为的最佳解决方案。由于注释无法继承,因此我尝试构建自定义运行器,但到目前为止没有成功。到目前为止,情况如下:

public class MyRunner extends Suite {

    public MyRunner(Class<?> klass, RunnerBuilder builder)
            throws InitializationError {
        super(klass, modifyBuilder(builder));
    }

    private static final RunnerBuilder modifyBuilder(RunnerBuilder builder) {
        if(AllDefaultPossibilitiesBuilder.class.isAssignableFrom(builder.getClass())) {    
            return new AllDefaultPossibilitiesBuilder(true) {
                @Override
                public Runner runnerForClass(Class<?> testClass)
                        throws Throwable {
                    List<RunnerBuilder> builders = Arrays.asList(
                            ignoredBuilder(),
                            annotatedBuilder(),
                            suiteMethodBuilder(),
                            junit3Builder(),
                            junit4Builder(),
                            myTestBuilder());

                    for (RunnerBuilder each : builders) {
                        Runner runner = each.safeRunnerForClass(testClass);
                        if (runner != null) {
                            return runner;
                        }
                    }
                    return null;
                }

                private RunnerBuilder myTestBuilder() {
                    return new RunnerBuilder() {

                        @Override
                        public MyAnnotationRunner runnerForClass(Class<?> testClass)
                                throws Throwable {
                            return new MyAnnotationRunner(testClass);
                        }
                    };
                }
            };
        } else {
            return builder;
        }
    }
}

还有MyAnnotationRunner 类:

public class MyAnnotationRunner extends BlockJUnit4ClassRunner {

    public MyAnnotationRunner(Class<?> klass) throws InitializationError {
        super(klass);
    }

    @Override
    protected List<FrameworkMethod> computeTestMethods() {
        return getTestClass().getAnnotatedMethods(MyTest.class);
    }

    @Override
    protected void validateTestMethods(List<Throwable> errors) {
        validatePublicVoidNoArgMethods(MyTest.class, false, errors);
    }
}

但是到目前为止,当我运行测试时,它并不关心 @MyTest 注释;事实上,如果我在构建器列表中注释掉 junit4Builder(), 行,它根本不会运行任何测试。

我是走错了路还是这是正确的想法但到目前为止还不完整? (而且我不能切换到 TestNG 或其他测试框架,以防有人提出建议。)

编辑:

解决方案(如 Bobbo 所建议的)不在上面发布的代码中 - 这似乎都是正确的。但是,@MyTest 注释缺少 @Retention 注释;正确的定义应该是这样的:

@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest { }

【问题讨论】:

    标签: java unit-testing junit annotations junit4


    【解决方案1】:

    确保您的 MyTest 注释设置为使用 Retention 注释在运行时保留,即

    @Retention( RetentionPolicy.RUNTIME )
    public @interface MyTest {}
    

    否则computeTestMethods() 中的MyAnnotationRunner 将返回一个空列表。

    此外,如果您还想运行带有 @Test 注释的任何内容,则需要将方法更改为如下所示:

    protected List<FrameworkMethod> computeTestMethods() {
        List<FrameworkMethod> methods = new ArrayList<>(); 
        methods.addAll(getTestClass().getAnnotatedMethods(Test.class));
        methods.addAll(getTestClass().getAnnotatedMethods(MyTest.class));
        return methods;
    }
    

    我还没有像您一样使用套件对此进行测试,我只是使用运行器运行测试类,它似乎可以按您的要求工作:

    @RunWith(MyAnnotationRunner.class)
    public class Tests {
        @Test
        public void testUsingNormalTestAnnotation() {
            Assert.fail();
        }
    
        @MyTest
        public void testUsingMyTestAnnotation() {
            Assert.fail();
        }
    }
    

    【讨论】:

    • 该死,@Retention 注释...如此简单,但那是我忘记的一件事。 :-D 更改computeTestMethods() 也是一个好点,我认为拥有JUnit4Builder 和我自己的Builder 可以完成这项工作,但显然不是。总之感谢! :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-02
    • 2019-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多