David B
David B

Reputation: 3581

NPE on spring autowires form TestExecutionListener

This might have been coded wrongly, but any idea how it should be done is appreciated.


I have this class TestClass which needs to inject many service class. Since I can't use @BeforeClass on @Autowired objects, I result on using AbstractTestExecutionListener. Everything was working as expected but when I'm on @Test blocks, all objects are evaluated null.

Any idea how to solve this?

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ProjectConfig.class })
@TestExecutionListeners({ TestClass.class })
public class TestClass extends AbstractTestExecutionListener {

    @Autowired private FirstService firstService;
    // ... other services

    // objects needs to initialise on beforeTestClass and afterTestClass
    private First first;
    // ...

    // objects needs to be initialised on beforeTestMethod and afterTestMethod
    private Third third;
    // ...

    @Override public void beforeTestClass(TestContext testContext) throws Exception {
        testContext.getApplicationContext().getAutowireCapableBeanFactory().autowireBean(this);

        first = firstService.setUp();
    }

    @Override public void beforeTestMethod(TestContext testContext) throws Exception {
        third = thirdService.setup();
    }

    @Test public void testOne() {
        first = someLogicHelper.recompute(first);
        // ...
    }

    // other tests

    @Override public void afterTestMethod(TestContext testContext) throws Exception {
        thirdService.tearDown(third);
    }

    @Override public void afterTestClass(TestContext testContext) throws Exception {
        firstService.tearDown(first);
    }

}

@Service
public class FirstService {
    // logic
}

Upvotes: 1

Views: 308

Answers (1)

Sam Brannen
Sam Brannen

Reputation: 31278

For starters, having your test class implement AbstractTestExecutionListener is not a good idea. A TestExecutionListener should be implemented in a stand-alone class. So you might want to rethink that approach.

In any case, your current configuration is broken: you disabled all default TestExecutionListener implementations.

To include the defaults, try the following configuration instead.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = ProjectConfig.class)
@TestExecutionListeners(listeners = TestClass.class, mergeMode = MERGE_WITH_DEFAULTS)
public class TestClass extends AbstractTestExecutionListener {
    // ...
}

Regards,

Sam (author of the Spring TestContext Framework)

Upvotes: 4

Related Questions