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

发布于 2024-12-11 00:44:39 字数 123 浏览 0 评论 0原文

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

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

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

I have a lot of unit tests files that basically execute the same @BeforeClass.

They start jetty web server, add some system properties.

So I'm wondering, is it possible to execute this only once, before unit test will be run?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

樱花落人离去 2024-12-18 00:44:39

您可以使用 @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;
            }
        }
    }
}

我不确定同步块是否真的需要,只是为了更好的措施而将其放入......

You could use the @RunWith annotation:

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

And implement a new 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;
            }
        }
    }
}

I'm not sure if the synchronized block is really needed, just threw it in for good measure...

╰つ倒转 2024-12-18 00:44:39

也许使用静态初始化器就可以了?尽管在运行单元测试时仅初始化某些字段一次并不是一个好主意,因为某些测试可能会将这些字段驱动到非法状态,从而阻碍其他测试的运行。

Maybe using a static initializer will do? Although it's not a very good idea to initialize some fields only once when running unit tests since some of the tests may drive the fields to an illegal state which will impede the running of the other tests.

赴月观长安 2024-12-18 00:44:39

除了 @Matt 关于创建自己的 Runner 的答案(我认为这是最好的方法)(请参阅此处的答案) ,我还创建了一个额外的 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)");
            }
        }
    }
}

In addition to @Matt's answer about creating your own Runner (which I thought was the best approach) (see the answer here), I also created an additional JUnit test that validates that all of my tests use my Runner (in case one of my developers forgets):

PS: Note this depends on 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)");
            }
        }
    }
}
紫轩蝶泪 2024-12-18 00:44:39

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

Do you run the test classes from a suite? A @BeforeClass on the suite class will run once, before any tests run.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文