0

I have the below flow

@InjectMocks private ClassToTest classToTest;

@Mock private ClassToInject classToInject;

@Before
public void setup() {
initMocks(this);
}

@Test
public void test() {
Classx mockClassObj = Mockito.mock(Classx.class);
when(classToInject.publicMethod1(mockClassObj)).thenReturn(1000);

classToTest.publicMethod();
}

I want to test public method of classToTest. Now this method makes call to a private method, which I am not mocking. Inside this private method another public method is called, which I want to mock publicMethod1. Instead of the private method making use of value 1000 it is behaving as if the publicMethod1 was not mocked and I get NPE inside the flow of the method somewhere. I tried using @Spy with classToTest and also I am using init.mocks/@RunWith but it fails.

In short it is something like

ClassToTest. publicMethod --> ClassToTest.privateMethod(not mocking) --> ClassToInject.publicMethod1(want to mock)

The class looks like below

class ClassToTest {
@Inject ClassToInject classToInject;

public publicMethod() {
privateMethod();
}

private privateMethod() {
int x = classToInject.publicMethod1();
// use the return value
// throw exception
}
Sonali Gupta
  • 494
  • 1
  • 5
  • 20
  • Can you put code of the class that you are testing? – Mirek Pluta Nov 28 '21 at 07:12
  • added a skeleton – Sonali Gupta Nov 28 '21 at 07:23
  • BTW, not related to your NPE but..`classToInject.publicMethod1(mockClassObj)` is useless as `mockClassObj` is created within the test. Any value/instance of `Classx` used in your SUT will not match this and hence it wouldn't return 1000. – Thiyagu Nov 28 '21 at 07:29
  • Check if mock injection is successful - Print `classToInject` and see if it comes from Mockito or it is null (or put a breakpoint in your IDE and check its toString). – Thiyagu Nov 28 '21 at 07:30
  • There is some discrepancy between the test code and actual code (method contract). To isolate the problem, test what I've suggested above. If it turns out to be null, then it means something is casing [InjectMocks](https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/InjectMocks.html) from injecting the mocked instances and Mockito wouldn't report any error. – Thiyagu Nov 28 '21 at 07:42
  • I've tested without the `@Inject` on the field (as I didn't have the lib in my classpath) and had `publicMethod1` as no-argument method returning an int and everything worked fine – Thiyagu Nov 28 '21 at 07:53
  • I printed the classToIject and it didn't return null. – Sonali Gupta Nov 28 '21 at 07:56
  • The main point is how to successfully link the classToInject to be used via that private method as well and value the when and return. – Sonali Gupta Nov 28 '21 at 07:57
  • Then it means there is no problem with `Mock` and `InjectMock`. The presence of a private method is irrelevant here. You need to add more details to the question (exact method signature - `publicMethod1` takes an argument as per your test but none in the place you call in SUT) and the exception you get – Thiyagu Nov 28 '21 at 08:12

1 Answers1

0

You mock classToInject.publicMethod1(mockClassObj) not classToInject.publicMethod1(). But your code invoked classToInject.publicMethod1();

int x = classToInject.publicMethod1(); // you invoked no parameter method

Check method which you want to invoke.

If You want to invoke classToInject.publicMethod1(), reference this code

@RunWith(MockitoJUnitRunner.class)
public class MockedTest {

    @InjectMocks
    private ClassToTest classToTest;
    
    @Mock
    private ClassToInject classToInject;
    
    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    }
    
    @Test
    public void test() {
        Mockito.when(classToInject.publicMethod1())
                .thenReturn(1000);
        
        classToTest.publicMethod();
    }
    
    
}

class ClassToTest{
    ClassToInject classToInject;
    
    public void publicMethod() {
        privateMethod();
    }
    
    private int privateMethod() {
        int x = classToInject.publicMethod1();
        throw new NullPointerException(String.valueOf(x));
    }
}

class ClassToInject{
    
    public int publicMethod1() {
        return 0;
    }
}

The result is 1000 success

java.lang.NullPointerException: 1000
bittap
  • 518
  • 1
  • 6
  • 15