【问题标题】:@Before method in TestRule is not called未调用 TestRule 中的 @Before 方法
【发布时间】:2015-05-22 14:56:05
【问题描述】:

我实现了一个 JUnit 4 TestRule(扩展了一个 ExternalResource),并将它作为 @ClassRule 注入到我的测试类中:我想在每个测试这个类,并最终将其拆除。

我的问题是我的@Before@After 规则方法在我的@Test 方法之前/之后根本没有被调用:知道为什么会这样吗?

最小的可编译示例:

package com.acme.test;

import static org.junit.Assert.assertNull;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.ExternalResource;

class Coffee {
    public void throwAway() {}
}

class CoffeeMachine extends ExternalResource {
    Coffee whatElse;    
    @Override protected void before() throws Throwable {
        whatElse = new Coffee();
    }

    @Override protected void after() {
        whatElse.throwAway();
    }

    public Coffee gimmieCoffee() { return whatElse; }
}

public class CoffeeTester {
    @ClassRule public static CoffeeMachine CM = new CoffeeMachine();

    @Test public void drinkACoffee() {
        Coffee c = CM.gimmieCoffee();
        assertNull(c);  // ---> Coffee is null!!                       (fuuuuuuuuuu...)
    }
}

我在这里有什么误解吗?请注意,非静态 @Rule 也会发生同样的情况。

我正在使用 JUnit 4.11

非常感谢您的任何提示。

【问题讨论】:

  • @Before 不应该与@Test 属于同一类吗?我也不确定覆盖 before() 是否足够,如果它没有被标记
  • 不是那样...但是谢谢 Dragondraikk。
  • 您显然没有尝试过您提供的代码,因为您在调用 gimmieCoffee 时有太多的 ms - 并且没有导入。这些东西我都修好了,没问题。请提供一个编译并实际演示问题的示例。
  • 复制粘贴编译的例子已经完成;)
  • @Campa 如果您希望人们帮助您解决问题,那么您发布的最小代码确实应该编译并可以复制粘贴。我已经运行了你的代码,就像上面一样,before()after() 正在被调用。我的assertNull(c) 行给出:java.lang.AssertionError: expected null, but was:。我不明白为什么它不适合你。在这里运行 junit 4.11 和 java 7。

标签: java junit-rule


【解决方案1】:

我认为这是您的测试运行程序的问题。也许某些插件安装了一个自定义运行程序,当您从 Ecilpse 运行测试时会使用该运行程序?

检查测试的运行配置并确保使用标准的 JUnit 4 测试运行器:

【讨论】:

  • 嘿,谢谢你,但我已经检查过了:一切都很正常。
【解决方案2】:

我认为这里没有问题,只是一个误解。首先,让我们将assert 读作it must be 并稍微修改一下您的代码(很明显,您的测试显示c must not be null 给了我们:assertNotNull(c);

我还添加了一些输出,以便向您展示发生了什么。请尝试运行它。

package com.acme.test;

import static org.junit.Assert.assertNotNull;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.ExternalResource;

class Coffee {
    public void throwAway() {}
}

class CoffeeMachine extends ExternalResource {
    Coffee whatElse;    
    @Override protected void before() throws Throwable {
        whatElse = new Coffee();
        System.out.println(" ### executing before: " + whatElse);
    }

    @Override protected void after() {
        whatElse.throwAway();
    }

    public Coffee gimmieCoffee() { return whatElse; }
}

public class CoffeeTester {
    @ClassRule public static CoffeeMachine CM = new CoffeeMachine();

    @Test public void drinkACoffee() {
        Coffee c = CM.gimmieCoffee();
        System.out.println(" ### executing test: " + c);
        assertNotNull(c); 
    }
}

对我来说,它给出了以下内容:

 ### executing before: com.acme.test.Coffee@28f67ac7
[VerboseTestNG] INVOKING: "com.acme.test.CoffeeTester" - com.acme.test.CoffeeTester.drinkACoffee()
 ### executing test: com.acme.test.Coffee@28f67ac7
[VerboseTestNG] PASSED: "com.acme.test.CoffeeTester" - com.acme.test.CoffeeTester.drinkACoffee() finished in 4 ms
[VerboseTestNG] 
[VerboseTestNG] ===============================================
[VerboseTestNG]     com.acme.test.CoffeeTester
[VerboseTestNG]     Tests run: 1, Failures: 0, Skips: 0
[VerboseTestNG] ===============================================

所以c 并不像您期望的那样为空。

【讨论】:

  • 感谢您的帮助!但是我得到### executing test: null。 :)
  • 这真是令人着迷 :) 您是否尝试过另一个 JUnit 版本?你能提供你所拥有的罐子的校验和吗?
  • 我使用 Eclipse 附带的 JUnit:org.junit_4.11.0.v201303080030/。校验和很好..我现在尝试使用 4.12,我的初始示例运行良好。
  • 谢谢@Renat 但是.. 404! :D
  • 我相信Eclipse被广泛使用,所以它不应该有这么明显的问题。我只能建议尝试一下(创建一个新项目,与执行者一起玩一下),以缩小可能的解释范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-12
  • 2023-03-16
  • 2019-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多