gpt4 book ai didi

java - 在 Suites 中使用 @BeforeClass @Before 编写 JUnit 测试

转载 作者:行者123 更新时间:2023-12-02 01:51:59 26 4
gpt4 key购买 nike

我正在使用 JUnit 4 来测试具有内存数据库的后端系统。我正在使用 @BeforeClass @Before @After@AfterClass

到目前为止,它在类(class)层面上运行良好。

@BeforeClass 包含数据库设置,该设置速度较慢,但​​每个测试 session 只需完成一次。

@Before 只是将石板擦干净,以便下一个测试运行。速度相当快。

我的测试看起来像这样:

class CompanyTest  {

@BeforeClass
public static void beforeAll() throws Exception {
BeforeAll.run(); //Setup In Memory Database!!! Very time intensive!!!
}
@Before
public void beforeTest() throws Exception {
BeforeTest.run(); //Setup data in database. Relatively quick
}


@Test
public void testCreateCompany() throws Exception {
///...
}
@Test
public void testDeleteCompany() throws Exception {
///...
}
@Test
public void testAdminCompany() throws Exception {
///...
}


@After
public void afterTest() {
AfterTest.run(); //clear data
}
@AfterClass
public static void afterAll() throws Exception {
AfterAll.run(); //tear down database
}
}

到目前为止,它在类(class)层面上运行良好。

我可以右键单击(在 Eclipse 中)单个测试,它将运行 @BeforeClass,然后运行 ​​@Before

我还可以(在 Eclipse 中)单击类本身,它只会运行 @BeforeClass 一次,然后在每次测试之前运行 @Before

...但是这个原则如何扩展到 Suite 级别?

我想在我的 Suite 中的所有类(class)之前运行 @BeforeClass。如果我这样写我的套件:

@Suite.SuiteClasses({ CompanyTest.class, CustomerTest.class, SomeOtherTest.class, })

public class AllTests {

@BeforeClass
public static void beforeAll() throws Exception {
BeforeAll.run();
}

@AfterClass
public static void afterAll() throws Exception {
AfterAll.run();
}
}

...我需要从所有测试类中删除@BeforeClass。这很烦人,因为我有很多测试类,而且我不想删除我的@BeforeClass,因为我想单独测试它们。

我基本上想说的是:

有没有一种简单的方法(在 IDE 中单击鼠标)在 (a) 方法级别、(b) 类级别和 (c) 套件级别测试 JUnit 测试,同时保持 session 级别设置和拆卸过程?

最佳答案

您需要的是通过不同的入口点管理全局状态。在 BeforeAll 或 AfterAll 类中,您可以保留一个静态引用,即一个 AtomicBoolean 来跟踪您是否已经执行它。

现在的问题 - 对于 beforeAll 和 afterAll 有两个单独的类 - 哪个类应该负责该标志。

因此我建议,您定义一个 Rule它包含所有设置和拆卸的逻辑(基本上是 BeforeAll 和 AfterAll 的所有代码),并管理用于跟踪初始化的全局状态。

基本上是这样的

class MyRule implements TestRule {
static final AtomicBoolean INITIALIZED = new AtomicBoolean();

@Override
public Statement apply(final Statement base, final Description description) {

return new Statement() {

@Override
public void evaluate() throws Throwable {
boolean needsTearDown = false;
try {
if (INITIALIZED.compareAndSet(false, true)) {
BeforeAll.run();
needsTearDown = true;
}
base.evaluate();
} finally {
if (needsTearDown) {
AfterAll.run();
INITIALIZED.set(false);
}
}
}
};
}
}

在您的测试和套件中只需添加

class YourTestOrSuite {

@ClassRule
public static MyRule rule = new MyRule();
}

关于java - 在 Suites 中使用 @BeforeClass @Before 编写 JUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52835367/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com