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

时间:2011-10-19 19:15:32

标签: java junit

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

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

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

4 个答案:

答案 0 :(得分: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)

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

答案 2 :(得分: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)");
            }
        }
    }
}

答案 3 :(得分:0)

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