如何将自定义Guice范围与TestNG集成?

时间:2014-12-05 18:12:38

标签: java junit testng guice

对于一些持续用于单个测试方法的JUnit测试,我们使用自定义Guice范围@TestScoped,并使用JUnit @Rule来适当地进入和退出范围。它看起来像这样:

public class MyJUnitTest {
    @Rule public CustomRule customRule = new CustomRule(MyModule.class);

    @Inject private Thing thing;

    @Test
    public void test1() {
        // Use "thing"
    }

    @Test
    public void test2() {
        // Assuming "Thing" is @TestScoped, we'll have a new instance
    }
}

我们开始在其他项目中使用TestNG进行一些测试,我们希望有类似的模式。到目前为止,我们已经提出了这个问题:

@Listeners(CustomTestNGListener.class)
@Guice(modules = MyModule.class)
public class MyTestNGTest {
    @Inject private Provider<Thing> thingProvider;

    @Test
    public void test1() {
        Thing thing = thingProvider.get();
        // Use "thing"
    }

    @Test
    public void test2() {
        Thing thing = thingProvider.get();
        // Assuming "Thing" is @TestScoped, we'll have a new instance
    }
}

public class CustomTestNGListener implements IHookable {
    @Override
    public void run(IHookCallBack callBack, ITestResult testResult) {
        TestScope.INSTANCE.enter();
        try {
            callBack.runTestMethod(testResult);
        } finally {
            TestScope.INSTANCE.exit();
        }
    }
}

此设计存在两个问题:

  • 与JUnit不同,TestNG为每个方法使用相同的测试类实例。这意味着我们必须注入Provider<Thing>而不仅仅是Thing,这很尴尬。

  • 出于某种原因,CustomTestNGListener正在我们的所有测试中运行,即使是那些没有@Listeners(CustomTestNGListener.class)注释的测试。我通过在侦听器本身中明确检查该注释来解决这个问题,但感觉就像是一个黑客(虽然我确实看到MockitoTestNGListener做同样的事情)。

对TestNG更熟悉的人是否有处理这些问题的建议?

1 个答案:

答案 0 :(得分:0)

而不是

public class MyTestNGTest {
    @Inject private Provider<Thing> thingProvider;

    @Test
    public void test1() {
        Thing thing = thingProvider.get();

在TestNG中你可以使用

public class MyTestNGTest {
    @Inject 
    private Thing thingInjected;
    private Thing thing;

    @BeforeTest
    public void doBeforeTest() {
        thing = thingInjected.clone();
    }

或者只需在thingProvider.get()中致电doBeforeTest(),最好有很多@ Test

public class MyTestNGTest {
    @Inject private Provider<Thing> thingProvider;
    private Thing thing;

    @BeforeTest
    public void doBeforeTest() {
        thing = thingProvider.get();
    }