Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Mockito verify works in JUnit but not Spock

Tags:

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!

like image 881
Philip Tenn Avatar asked May 21 '13 19:05

Philip Tenn


2 Answers

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.

like image 163
Peter Niederwieser Avatar answered Sep 24 '22 22:09

Peter Niederwieser


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
like image 27
Jeff Price Avatar answered Sep 21 '22 22:09

Jeff Price