在任何junit测试运行之前执行一些代码

问题描述 投票:6回答:4

我有很多单元测试文件基本上执行相同的@BeforeClass

他们启动jetty web服务器,添加一些系统属性。

所以我想知道,在单元测试运行之前,是否有可能只执行一次?

java junit
4个回答
10
投票

你可以使用@RunWith注释:

@RunWith(JettyRunner.class)
public class MyAwesomeTest {
    @Test
    //...
}

并实施一个新的Runner

public class JettyRunner extends BlockJUnit4ClassRunner {
    private static boolean initialized = false;

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

        synchronized (JettyRunner.class) {
            if (!initialized) {
                System.out.println("Let's run jetty...");
                initialized = true;
            }
        }
    }
}

我不确定是否真的需要同步块,只是把它扔进去了...


1
投票

也许使用静态初始化程序会做什么?虽然在运行单元测试时仅初始化一些字段并不是一个好主意,因为某些测试可能会将字段驱动到非法状态,这将妨碍其他测试的运行。


1
投票

除了@Matt关于创建自己的Runner的答案(我认为这是最好的方法)(参见the answer here),我还创建了一个额外的JUnit测试,验证我的所有测试都使用了我的Runner(如果我的一个开发人员忘记了):

PS:请注意这取决于OpenPOJO

@Test
public void ensureAllTestsUseEdgeRunner() {
    for (PojoClass pojoClass : PojoClassFactory.getPojoClassesRecursively("your.base.package", null)) {
        boolean hasTests = false;
        for (PojoMethod pojoMethod : pojoClass.getPojoMethods()) {
            if (hasTests = pojoMethod.getAnnotation(Test.class) != null) {
                break;
            }
            if (hasTests = pojoMethod.getAnnotation(BeforeClass.class) != null) {
                break;
            }
            if (hasTests = pojoMethod.getAnnotation(Before.class) != null) {
                break;
            }
            if (hasTests = pojoMethod.getAnnotation(AfterClass.class) != null) {
                break;
            }
            if (hasTests = pojoMethod.getAnnotation(After.class) != null) {
                break;
            }
        }
        if (hasTests) {
            PojoClass superClass = pojoClass;
            boolean hasRunWith = false;
            while (superClass != null) {
                // ensure it has the RunWith(EdgeJUnitRunner.class) annotation
                RunWith runWithAnnotation = superClass.getAnnotation(RunWith.class);
                if (runWithAnnotation != null && runWithAnnotation.value() == EdgeJUnitRunner.class) {
                    hasRunWith = true;
                    break;
                }
                superClass = superClass.getSuperClass();
            }

            if (!hasRunWith) {
                throw new RuntimeException(pojoClass.getClazz().getName() + " should be annotated with @RunWith(EdgeRunner.class)");
            }
        }
    }
}

0
投票

你从套件中运行测试类吗?在任何测试运行之前,套件类上的@BeforeClass将运行一次。

© www.soinside.com 2019 - 2024. All rights reserved.