1

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?

KitKarson
  • 5,211
  • 10
  • 51
  • 73
  • 1
    The common behaviour of TestNG is to share the ITestContext at least for the entire suite. People are using it to share information between tests with attributes of ITestContext. You can use dependency injection as described in https://testng.org/doc/documentation-main.html#guice-dependency-injection, but I would recommend not to interfere with the underlying infrastructure. – Jens Dibbern Apr 14 '19 at 19:21

1 Answers1

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);
    }

}
vins
  • 15,030
  • 3
  • 36
  • 47