Philip Tenn
Philip Tenn

Reputation: 6083

Simple Mockito verify works in JUnit but not Spock

Using the most basic example from Mockito's examples page, I am able to run successfully in JUnit.

However, when I run the same test in Spock, it fails.

JUnit/Java version (this passes):

import org.junit.Test;

import java.util.List;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

public class SimpleJunitTest
{
    @Test
    public void basicMockTest()
    {
        List mockedList = mock(List.class);

        //using mock object
        mockedList.add("one");
        mockedList.clear();

        //verification
        verify(mockedList).add("one");
        verify(mockedList).clear();
    }
}

Spock/Groovy version (this fails):

import static org.mockito.Mockito.mock
import static org.mockito.Mockito.verify


class SimpleSpockTest extends spock.lang.Specification
{
    def "Basic Mock Test"()
    {
        given:
            //mock creation
            List mockedList = mock(List.class);

        when:
            //using mock object
            mockedList.add("one");
            mockedList.clear();

        then:
            //verification
            verify(mockedList).add("one");
            verify(mockedList).clear();
    }

}

Here is the error I get when the Spock Test fails:

Condition not satisfied:

verify(mockedList).add("one")
|      |           |
|      |           false
|      $java.util.List$$EnhancerByMockitoWithCGLIB$$172e393a@613043d2 (renderer threw    
NullPointerException)
$java.util.List$$EnhancerByMockitoWithCGLIB$$172e393a@613043d2 (renderer threw 
NullPointerException)

at SimpleSpockTest.Basic Mock Test(SimpleSpockTest.groovy:25)

Any ideas or suggestions? I really like Spock and Mockito and am hoping to get them working well together. Thank you very much!

Upvotes: 25

Views: 6749

Answers (2)

Jeff Price
Jeff Price

Reputation: 41

I have a use case requiring PowerMockito to mock final methods in Java classes (where Spock mocking won't work), but also need to verify they did get called, because the final methods are builder-style and return "this", which makes the tests pass even if the mocked call wasn't called.

My solution was to append "|| true" to my verify calls, like this:

given:
when(myMock.setSomething("xyzzy")).thenReturn(myMock)

when:
def result = objectBeingTested.isExecutedWith("xyzzy")

then:
result == expectedResult
Mockito.verify(myMock).setSomething("xyzzy") || true         // this passes
Mockito.verify(myMock).setSomething("wrongValue") || true    // this FAILS appropriately

Upvotes: 4

Peter Niederwieser
Peter Niederwieser

Reputation: 123996

Roughly speaking, a then-block may only contain assertions in the form of boolean expressions. A Mockito verification expression doesn't fit this contract, as it will return a falsy value (null, false, 0) when it passes, which is interpreted as a failed assertion by Spock.

To solve this problem, you can either write a helper method that wraps around the verification expressions and always returns true, or you can use Spock's built-in mocking framework instead of Mockito.

Upvotes: 28

Related Questions