Reputation: 55
I am dealing with a design situation and I am not sure how to solve it or if I am doing anything wrong with my micro design.
public abstract class A implements SomeFrameworkInterface {
private final Param1 a1;
@Inject
private Param2 a2;
protected A(Param1 a1) {
this.a1 = a1;
}
@Override
public someFrameworkInterfaceMethod() {
//code
doMyStuff();
}
protected abstract void doMyStuff();
}
@Named
@SomeCustomAnnotation(property="someProperty")
public class B extends A {
@Inject
public B(Param1 b1) { //b1 is different for every implementation of class A, through some annotations
super(b1);
}
@Override
protected void doMyStuff() {
//code
}
}
Restrictions are the following:
Upvotes: 1
Views: 545
Reputation: 55
I find the solution to test this, but it's look a little weird. I mean I do not understand why or how is this happening, but it does the job in a clean way. Test class looks like:
@RunWith(MockitoJUnitRunner.class)
public BTest {
@Mock
private Param1 mockParam1;
@Mock
private Param2 mockParam2;
@InjectedMocks
private A b = new B(null);
@Test
public someFrameworkInterfaceMethodTest() {
when(...).thenReturn(...)
b.someFrameworkInterfaceMethod();
verify(...).someCall(any());
}
}
I had a hard time to figure it out why Param1 a1 remained null and tried to find out different solutions. But it seems Mockito injects fields again post construct (after "new B(null)" is called - if fields are null or not sure). Param2 a2 was mocked by mockito while Param1 a1 remained null and this happened because of the "final" keyword on Param1 a1 in B class.
Upvotes: 0
Reputation: 4014
It's impossible to pass any parameter to A's constructor without going through B's, because you are actually constructing an instance of B. A's constructor is only delegated to in order to construct the "A part" of the B instance.
The most you can do is pass some sort of "typeless" parameter to B's constructor, so that at least B won't know about Param2
, but that cure already sounds worse than the disease even as I was writing it down...
I don't see injecting Param2
post-construction making the code any less testable. OTOH, using a static field would most certainly do.
Upvotes: 0