25

Consider the following method:

public boolean isACertainValue() {
        if(context.getValueA() != null && context.getValueA().toBoolean() == true) {
        if(context.getType() != null && context.getType() == ContextType.certainType) {
            return true;
        }
    }
    return false;
}

I did not write this code, it is ugly as hell, it is totally overcomplicated but I have to work with it.

Now I want to test a method that relies on a call to this method.

I thought I could deal with this by:

Mockito.when(spy.isACertainValue()).thenReturn(true); because that's the case I want to test.

But it doesn't work as it is still calling the method-body :/

I get nullpointers or rather I get something along the lines of

misusing.WrongTypeOfReturnValue; Boolean cannot be returned by getValueA(). getValueA() should return ValueA

So I tried (as a workaround) to do:

Mockito.when(contextMock.getValueA()).thenReturn(new ValueA()); and Mockito.when(contextMock.getType()).thenReturn(ContextType.certainType);

but then I get a nullpointer that I cant seem to be able to debug.

So, how is it done right in this case?

Tunaki
  • 132,869
  • 46
  • 340
  • 423
  • 1
    That is exactly how to do it, but maybe there is a value IN that valueA you need further on in your test, so you should also mock the object returned, not just return an instance instantiated with a (default) constructor. – Stultuske Dec 16 '15 at 10:01
  • I had similar problem (a method in a super class was not mocked). The conclusion was that it was a bug in Mockito. Updating Mockito to 2.28.2 helped. – Arkadiusz Cieśliński Jul 26 '19 at 12:35

2 Answers2

39

When you are invoking

Mockito.when(spy.isCertainValue()).thenReturn(true);

the method isCertainValue() is getting called here. This is how Java works: to evaluate the argument of Mockito.when, the result of spy.isCertainValue() must be evaluated so the method must be called.

If you don't want that to happen, you can use the following construct:

Mockito.doReturn(true).when(spy).isCertainValue();

This will have the same mocking effect but the method won't be called with this.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
1

This code is correct:

Mockito.when(contextMock.getType()).thenReturn(ContextType.certainType);

But you are getting NullPointerException because you didn't define the Mocking value that should be defines, well I'm using Spring, in my context file when I define @Autowired bean I define it this way:

<bean id="contextMock" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.example.myspringproject.bean.ContextMock" />
</bean>
Chris Sim
  • 4,054
  • 4
  • 29
  • 36