I implemented a JUnit 4 TestRule
(extending an ExternalResource
), and injected it as a @ClassRule
in my test class: I want to initialize a resource once for all in every test of this class, and tear it down eventually.
我实现了一个JUnit 4 TestRule(扩展一个ExternalResource),并在我的测试类中将它作为@ClassRule注入:我想在这个类的每个测试中为所有资源初始化一次,并最终将其拆除。
My issue is that my @Before
and @After
rule-methods are not called at all before/after my @Test
method: any idea why this is happening?
我的问题是我的@Best方法之前/之后根本没有调用@Before和@After规则方法:任何想法为什么会这样?
Minimal compilable example:
最小的可编辑示例:
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...)
}
}
Is there something I am misunderstanding here? Note that the same happens with a non-static @Rule
.
我有什么误解吗?请注意,非静态@Rule会发生同样的情况。
I am using JUnit 4.11.
我正在使用JUnit 4.11。
Thank you very much for any hint.
非常感谢您的任何提示。
2 个解决方案
#1
I think this is a problem with your test runner. Maybe some plugin has installed a custom runner which is used when you run your tests from Ecilpse?
我认为这是你的测试运行员的一个问题。也许某些插件安装了一个自定义运行器,当你从Ecilpse运行测试时会使用它?
Check the run configuration for your test and make sure that the standard JUnit 4 test runner is used:
检查测试的运行配置,并确保使用标准的JUnit 4测试运行器:
#2
I see no issue here, but just a misunderstanding. First of all, let's read assert
as it must be
and change your code a bit (it is obvious your test says c must not be null
which gives us: assertNotNull(c);
我在这里看不到任何问题,但只是一个误解。首先,让我们读取必须的断言并稍微改变你的代码(显然你的测试说c不能为null,它给出了我们:assertNotNull(c);
I've also added some output in order to show you what is going on. Please try to run it.
我还添加了一些输出,以告诉你发生了什么。请尝试运行它。
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);
}
}
For me it gives the following:
对我来说,它给出了以下内容:
### 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] ===============================================
So c
is not null as you expect it to be.
所以c不是你想象的那样。
#1
I think this is a problem with your test runner. Maybe some plugin has installed a custom runner which is used when you run your tests from Ecilpse?
我认为这是你的测试运行员的一个问题。也许某些插件安装了一个自定义运行器,当你从Ecilpse运行测试时会使用它?
Check the run configuration for your test and make sure that the standard JUnit 4 test runner is used:
检查测试的运行配置,并确保使用标准的JUnit 4测试运行器:
#2
I see no issue here, but just a misunderstanding. First of all, let's read assert
as it must be
and change your code a bit (it is obvious your test says c must not be null
which gives us: assertNotNull(c);
我在这里看不到任何问题,但只是一个误解。首先,让我们读取必须的断言并稍微改变你的代码(显然你的测试说c不能为null,它给出了我们:assertNotNull(c);
I've also added some output in order to show you what is going on. Please try to run it.
我还添加了一些输出,以告诉你发生了什么。请尝试运行它。
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);
}
}
For me it gives the following:
对我来说,它给出了以下内容:
### 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] ===============================================
So c
is not null as you expect it to be.
所以c不是你想象的那样。