I have TestNG tests that use an instance of a class called Server. This instance is autowired in my tests using the Spring Test framework. As suggested here, I would like to externalize start and stop of the Server in beforeTestClass() and afterTestClass() methods by implementing the TestExecutionListener interface. To do this, I first use Java reflection to get the Server fields in the test class and then invoke start and stop in beforeTestClass() and afterTestClass() methods respectively. The TestContext that is passed as an argument in to these methods encapsulates the instance of the test. However the TestContext.getInstance is null, which means that I cannot get the value of the field (a Server object) at runtime.
Here is an example:
public class Server
{
public void start()
{
System.out.println("Started");
}
public void stop()
{
System.out.println("Stopped.");
}
}
@Configuration
public class ServerConfig
{
@Bean
public Server server()
{
return new Server();
}
}
public class ServerStartStopListener implements TestExecutionListener, Ordered
{
@Override
public void afterTestClass(TestContext testContext)
{
//testContext.getTestInstance() is null
}
@Override
public void afterTestMethod(TestContext testContext){}
@Override
public void beforeTestClass(TestContext testContext)
{
//testContext.getTestInstance() is null
}
@Override
public void beforeTestMethod(TestContext testContext){}
@Override
public void prepareTestInstance(TestContext testContext){}
@Override
public int getOrder()
{
return 6000;
}
}
@ContextConfiguration(classes={ServerConfig.class})
@TestExecutionListeners(listeners=ServerStartStopListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS)
public class AppTest extends AbstractTestNGSpringContextTests
{
@Autowired
private Server server;
@Test
public void test()
{
System.out.println("Server should be started at this point");
}
}
There are workarounds. This suggests to the autowired bean from the test instance's ApplicationContext. Another one is to use beforeTestMethod() and afterTestMethod() methods. However, they do not suit my needs.
As per beforeTestClass() and afterTestClass() methods in org.springframework.test.context.TestContextManager, the above behaviour seems intended. Could someone explain why?