TestNG - Accessing ITestContext in Guice Module

2019-08-26 22:23发布

问题:

I was trying to do as per this question.

Is there a way to inject ITestContext from TestNg to guice module?

Consider this:

public class TestParentModule extends AbstractModule {

    private ITestContext iTestContext;

    public TestParentModule(ITestContext iTestContext){
        this.iTestContext = iTestContext;
    }

    @Override
    protected void configure() {
        System.out.println("Parent module called");
        bind(ITestContext.class).toInstance(iTestContext);
    }

}

public class TestModule extends AbstractModule {

    @Inject
    private ITestContext iTestContext;

    @Override
    protected void configure() {
        System.out.println("configure is called :: " + iTestContext.getName());
    }
}

Suite

<suite name="My suite" parent-module="com.mypackage.guice.TestParentModule">
    <test name="Test1" >
        <classes>
            <class name="com.mypackage.SampleTest"/>
        </classes>
    </test>

    <test name="Test2" >
        <classes>
            <class name="com.mypackage.SampleTest"/>
        </classes>
    </test>

    <test name="Test3" >
        <classes>
            <class name="com.mypackage.SampleTest"/>
        </classes>
    </test>

</suite>

The test class is annotated with

@Guice(modules = TestModule.class)

Output::

Parent module called
configure is called :: Test1
configure is called :: Test1
configure is called :: Test1

Interestingly it injects same ITestContext instance every time? Is it not a bug in TestNG?

I was hoping that I would be seeing

Parent module called
configure is called :: Test1
configure is called :: Test2
configure is called :: Test3

How can I access ITestContext in the GuiceModule?

回答1:

The TestParentModule clearly binds the ITestConext to specific instance. Also ParentModule is invoked only once. So it is basically going to inject the same instance. Not sure if it is a bug. Could be as per their design!

    @Override
    protected void configure() {
        System.out.println("Parent module called");
        bind(ITestContext.class).toInstance(iTestContext);
    }

As Jens has pointed out in the comment, using IModuleFactory would solve your problem.

public class ModuleFactory implements IModuleFactory {

    @Override
    public Module createModule(ITestContext iTestContext, Class<?> aClass) {
        return new TestModule(iTestContext);
    }

}

public class TestModule extends AbstractModule {

    private ITestContext iTestContext;

    public TestModule(ITestContext iTestContext){
        this.iTestContext = iTestContext;
    }

    @Override
    protected void configure() {
        //do something with iTestConext
        bind(ITestContext.class).toInstance(iTestContext);
    }

}


标签: testng guice