I am having an issue with Null Pointer while trying to use Mockito with UT
ServiceClass{
@Inject
private UtilsOne;
...
public void methodOne(object1, object2, List<> elements){
--- some logic ---
UtilsOne.method1();
--- some logic ---
UtilsOne.method2();
--- some logic ---
Element e = UtilsOne.createElement(type,id);
elements.add(e);
}
...
}
UtilsOne{
@Inject
private UtilsTwo;
...
public void method1(){
--- some logic ---
}
public void method2(){
--- some logic ---
}
public Element createElement(Object type, String id){
--- some logic ---
UtilsTwo.callMethod(type, id);
}
...
}
This is how the structure of the classes looks in general.
I used @InjectMocks
on the ServiceClass
and @Spy
on the UtilsOne
so far the functionality worked for me, when calling methodOne
, everything seems to work as expected but,
inside methodOne
when reaching the UtilsTwo.callMethod()
it throw a Null Pointer exception, I tried to figure out how to make the class (UtilsTwo) not Null so it will work but I did not figure it out.
If something is not clear please tell me I will edit and explain it better Thanks in advance.
***Edited
After reading the answer I made it clearer, I want to check the content of the List<> elements
, each Utils is has its own method and they have a connection - it will not be right to change the structure as it is now
CodePudding user response:
In general, you should only mock the direct dependencies of the class you're testing, not the dependencies of the decencies. In your example, if you are testing ServiceClass
, you should just mock UtilsOne
, not UtilsTwo
. So inject a mock of UtilsOne
into ServiceClass
and mock the response of method3()
- that way no reference to UtilsTwo
is ever made.
You might also want to test that UtilsOne.method3()
is working correctly and interacting with UtilsTwo
as you expect, but that should be a totally separate set of tests, where you mock UtilsTwo
injected into. a real instance of UtilsOne
.
CodePudding user response:
After a lot trial and error, I used ReflectionTestUtils
and it solved my problems
This is the general structure
ReflectionTestUtils.setField(ClassWhereTheFieldIsAt, "NameOfFieldInClass", NameOfFieldInTest);
in the test class if it looks like this
@Spy
private UtilsOne utilsOne;
private UtilsTwo utilsTwo;
@Test
public void testElements(){
ReflectionTestUtils.setField(utilsOne, "utilsTwo", utilsTwo);
....
}
For me the the NameOfFieldInClass
and NameOfFieldInTest
are the same.