依赖功能JUnit测试不能共享静态字段

时间:2017-03-15 10:37:11

标签: java testing junit static

我有以下测试(针对此问题进行了简化):

@FixMethodOrder(MethodSorters.JVM)
public class ArticleTest {

    private static Article article;

    @Test
    public void testCreateArticle() {
        articleService.create("My article");
        article = articleService.findByTitle("My article");
        assertNotNull(article);
    }

    @Test
    public void testUpdateArticle() {
        article.setTitle("New title");
        articleService.save(article);
        assertNull(articleService.findByTitle("My article"));
        article = articleService.findByTitle("New title");
        assertNotNull(article);
    }

}

testCreateArticle成功传递,但testUpdateArticle在第一行失败,因为articlenull,因此抛出了一个NPE(尽管第一个测试断言{{1} }不是article)。

任何人都明白为什么?请注意,我使用Play Framework运行测试(喜欢字节码操作),所以这可能会以某种方式相关......

另外,我知道有依赖测试是一种不好的做法,但是IRL,这不是一个单元测试,而是一种测试场景,所以我只想尝试依赖测试自己理解为什么人们不喜欢它们;)

但无论如何,静态字段应该在测试之间共享,我错了吗?

更新:我知道我可以在null中重新创建一篇文章,但真正的测试更复杂(可能我在创建MVCE时失败了......)。假设我有第三个测试依赖于第二个测试(取决于第一个),等等。第一个测试不需要特别的,第二个需要创建的文章,第三个需要创建然后更新的文章等。我想通过保持测试之间的状态(使它们依赖于那些)来避免每次重做所有数据库操作。

2 个答案:

答案 0 :(得分:1)

更好的方法是使用@Before注释在每次测试之前重新创建文章对象。

@Before
public void setUp() {
    articleService.create("My article");
}

这样,文章对象不需要是静态的,并且使测试更容易。

注意:不要忘记在@After方法

中清理文章
@After
public void tearDown() {
    articleService.delete("My article");
}

答案 1 :(得分:1)

我无法重现您的行为:

@FixMethodOrder
public class RemoveMeTest {
private static String string;

@Test
public void testOne() {
    string  = "foo";
}

@Test
public void testTwo() {
    System.out.println("in test two: " + string) ;
}
}

输出确实是" foo"。您是否为测试用例提供了特殊配置或测试运行器?

测试用例应该真的,真的不依赖于其他测试用例。我也想提一下,即使你的案子更复杂而其他人已经提到它了;) 测试A失败,B和C也会失败,即使它们有效。您更改了测试A,运行,但B和C失败,在您的示例中更改String"我的文章",即使它们有效。如果C失败,则必须先运行A和B,以验证C是否再次运行。

最糟糕的是imo:它增加了复杂性,这是完全没必要的。因为我认为:测试代码与生产代码一样有价值,指的是可读性,复杂性,可维护性等。理解10行代码,而不是30行代码,要容易得多。你可以相信我的经验。有经验我的意思是:我做错了很多...而且自我对过去的自己非常生气(懒惰):P。话虽如此:我更喜欢一个易于理解的测试案例而不是n db往返,从长远来看它便宜得多......