Home > Back-end >  Mock Class within an Class- Using the original behavior of these Classes when calling methods
Mock Class within an Class- Using the original behavior of these Classes when calling methods

Time:08-10

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.

  • Related