Reputation: 2174
I have a test class which is testing an other class method
Other class is structured like this
@Component
public abstract class ParentOpManager{
@Autowired
private ProcessorRequestWrapper processorRequestWrapper;
@Autowired
private XYProcessor xyProcessor;
}
@Component("childManager")
public class ChildOperationManager extends ParentOpManager{
}
public abstract class ParentClass{
protected final RequestWrapper requestWrapper;
protected final ParentOpManager parentOpManager;
public ParentClass(final RequestWrapper requestWrapper, final ParentOpManager parentOpManager){
this.requestWrapper = requestWrapper;
this.parentOpManager = parentOpManager;
}
}
further I have, child classes extending this class
public class ChildClass extends ParentClass{
@Autowired
private NinjaManager ninjaManager;
@Autowired
public ChildClass(final RequestWrapper requestWrapper, @Qualifier("childManager")final ParentOpManager parentOpManager){
super(requestWrapper, parentOpManager);
}
public void methodA() throws Exception {
Request item = requestWrapper.findItem(); // Problem place 1
}
public void methodB() throws Exception {
Request item = ninjaManager.findItem(); // Problem place 2
}
}
I need to test methods of ChildClass
. For this I have written a test class.
//@RunWith(MockitoJunitRunner.class)
//@ContextConfiguration
public class TestClass{
@Mock
ChildOperationManager chOpManager;
@Mock
RequestWrapper requestWrapper;
@InjectMocks
ChildClass childObject;
@Before
public void setup(){
MockitoAnnotations.initMocks(this);
}
@Test
public void testSomeMethodA() throws Exception{
childObject.methodA();
}
}
So, the problem is when I am class methodA from test class, requestWrapper is NULL. I can not understand why this is happening ?
EDIT:
If i do like
@Mock
ChildOperationManager chOpManager = new ChildOperationManager();
@Mock
RequestWrapper requestWrapper;
@InjectMocks
ChildClass childObject = new childObject(requestWrapper, chOpManager);
Problem seams to be resolved. There is some other problem which might be some permission issue. But do you think doing this way is good approach ?
Upvotes: 0
Views: 484
Reputation: 3072
Problem is that Mockito tried to inject mock via constructor in first step.
public class DefaultInjectionEngine {
public void injectMocksOnFields(Set<Field> needingInjection, Set<Object> mocks, Object testClassInstance) {
MockInjection.onFields(needingInjection, testClassInstance)
.withMocks(mocks)
.tryConstructorInjection() <-- Here
.tryPropertyOrFieldInjection()
.handleSpyAnnotation()
.apply();
}
}
And if it found proper constructor, it doesn't try to inject mocks via property or field.
In your case you have constructor for ChildClass, which was picked by Mockito, but you don't initialize a fields in ChildClass.
As workaround, you can resolve it in this way (just don't use mockito injections):
RequestWrapper wrapper;
ChildOperationManager childOperationManager;
ChildClass childObject;
@Before
public void setUp() {
wrapper = Mockito.mock(RequestWrapper.class);
childOperationManager = Mockito.mock(ChildOperationManager.class);
childObject = new ChildClass(wrapper, childOperationManager );
}
Upvotes: 1
Reputation: 17035
Your error is this:
@Autowired
public ChildClass(final RequestWrapper requestWrapper, @Qualifier("childManager")final ParentOpManager parentOpManager){
super(requestWrapper, parentOpManager);
}
public void methodA() throws Exception {
Request item = requestWrapper.findItem(); // this requestWrapper is null
}
You don't assign the requestWrapper reference in the child. So it remains null.
You should just remove the member variable requestWrapper
and parentOpManager
from the child. this way, you'll use the parent's one, which is initialized.
Upvotes: 1