Better support for @Nested classes
JHahnHRO opened this issue · 2 comments
Currently, if one has a JUnit5 test class with a @WeldSetup WeldInitiator
field and a @Nested
subclass, the Setup-Field of the enclosing class is not picked up by the nested class. Every nested class seems to need its own Setup-Field.
Example application:
@ApplicationScoped
public class HelloService {
@Inject
Helper helper;
public String sayHello() {
return "Hello " + helper.getName();
}
}
@Dependent
public class Helper {
public String getName() {
return "World";
}
}
Example test:
@ExtendWith(WeldJunit5Extension.class)
class HelloServiceTest {
@WeldSetup
WeldInitiator weldInitiator = configureWeld();
private WeldInitiator configureWeld() {
return WeldInitiator.from(HelloService.class)
.addBeans(MockBean.of(Mockito.mock(Helper.class), Helper.class))
.build();
}
@Inject
Helper helper;
@Inject
HelloService service;
@Test
void testSayHello() {
when(helper.getName()).thenReturn("Mock");
final String actual = service.sayHello();
assertThat(actual).isEqualTo("Hello Mock");
}
@Nested
class NestedTest{
@WeldSetup
WeldInitiator weldInitiator = configureWeld(); // (!)
@Test
void testSayHelloAgain() {
when(helper.getName()).thenReturn("nested Mock");
final String actual = service.sayHello();
assertThat(actual).isEqualTo("Hello nested Mock");
}
}
}
Not including the field marked (!) will lead to a DeploymentException
:
WELD-001408: Unsatisfied dependencies for type Helper with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject org.example.HelloServiceTest.helper
at org.example.HelloServiceTest.helper(HelloServiceTest.java:0)
which is (at least for me) confusing, because there obviously is a CDI-Container running, because it is throwing the DeploymentException. I just assumed that if a container is running, then the @ExtendWith
on the enclosing class was picked up, and therefore the @WeldSetup
field should be picked up too. Obviously that was not the case.
In hindsight, I can guess what happens under the hood: The extension only looks for fields in the test class and HelloServiceTest.weldInitiator
is not a field of HelloServiceTest$NestedTest
.
But it would be nice to have this behaviour at least documented. Better yet, the error message could suggest to define an appropriate field for every nested test class. Even better yet: The extension could detect that a test class is nested and check the instance of the enclosing itself.
Hi and thanks for the report.
I'll add it to my TODO list and look into it but it probably won't be right away.
If you have the time and will, I'd be happy to accept a contribution.
From the top of my head, I am not sure how we search for WeldInitiator
but I think we are looking only in given test class and then its superclasses. If that's the case, we could just expand the algorithm to look into:
- Test class
- Any superclass of the test class
- Check for enclosing class and any
WeldInitiator
in them - Super classes of enclosing classes
Yes, I think I can do that. It's also on my TODO list, but it probably won't be right away :-)
EDIT: Surprisingly, I did find some time today. :-) PR see below