arquillian-core
arquillian-core copied to clipboard
NullPointerException when interceptBeforeEach in @Nested class invoke method that has fields with @EJB or @Inject annotation
Bug report / Enhancement
Issue Overview
NPE is fired before @Test method is executed in @Nested class.
Expected Behaviour
NPE isn't throw and @Test runs successfuly
Steps To Reproduce
@ExtendWith(ArquillianExtension.class)
@ArquillianSuiteDeployment
@Transactional(TransactionMode.ROLLBACK)
public abstract class ArquillianBasedTest {
private static final Logger LOG = LogManager.getLogger();
@EJB
private ServerStateService serverStateService;
@Inject
private IAppServerPathProvider appServerPathProvider;
@BeforeEach
protected void setUp() throws Exception {
waitForServer();
}
private void waitForServer() throws Exception {
org.awaitility.Awaitility.await().until(() -> ServerState.READY.equals(serverStateService.getServerState())); //here occured NPE as serverStateService is null
}
}
class TypeLevelReferenceDaoIntegrationTest extends ArquillianBasedTest {
@EJB
private ITypeLevelReferenceDao daoUnderTest;
@Test
void testFindTypeLevelReferenceByTypeElementPathViaReferenceTypeElement() {
//tests that are directly in class runs fine. All EJB, CDI fields are injected
}
@Nested
class NestedTest {
@Test
void testx() {
System.out.println("Hello world from nested test "); //this line is never invoked as first it run @BeforeEach and failed on NPE
}
}
When debug it:
- when it is "parent" test method then in org.jboss.arquillian.junit5.container.JUnitJupiterTestRunner.execute(Class<?>, String) testClass is TypeLevelReferenceDaoIntegrationTest
- org.jboss.arquillian.junit5.ArquillianExtension.interceptBeforeEachMethod(Invocation<Void>, ReflectiveInvocationContext<Method>, ExtensionContext)
- invocation delegate target is instance of testClass and has all fields correctly injected
- when it is nested case then testClass is TypeLevelReferenceDaoIntegrationTest$NestedTest
- invocation delegate target is integration.de.ids.acos.et.server.dao.ooe.type.TypeLevelReferenceDaoIntegrationTest@3d91b4a1 and all fields are null
the condition predicate says that it runs insideArquillian
TestMethodTestDescriptor: [engine:junit-jupiter]/[class:integration.de.ids.acos.et.server.dao.ooe.type.TypeLevelReferenceDaoIntegrationTest]/[nested-class:NestedTest]/[method:testx()]
testInstances are: [integration.de.ids.acos.et.server.dao.ooe.type.TypeLevelReferenceDaoIntegrationTest@3d91b4a1, integration.de.ids.acos.et.server.dao.ooe.type.TypeLevelReferenceDaoIntegrationTest$NestedTest@5dcbafbe]
I am also having this same issue. However it seems like it's not necessarily an issue with @BeforeEach
but an issue with injected fields not being injected within the context of running tests within a @Nested
class.
@ExtendWith(ArquillianExtension.class)
public class FooTest {
@Inject
private Foo foo;
@BeforeEach
public setUp(){
//foo will be set if running against outerTest() but will be null if running for nestedTest()
}
@Test
public outerTest(){
assertThat(foo, is(notNullValue()); //This is fine
}
@Nested
public class NestedFooTest(){
@Test
public nestedTest(){
assertThat(foo, is(notNullValue()); //foo will be null
}
}
}
The above example is stripped down do highlight where Injection seems to work but my actual code looks very like the original example with an abstract arqullian test class annotated with @ArquillianSuiteDeployment
in case that is making a difference.