Search code examples
groovygrailsspock

Spock Mock not updating the fields


Suppose we have a class that we want to mock.

class Apple {
 Color color
 bool isFresh
}

We mock it with Mock. We execute the code we need to test. Mocked Apple object gets its Color color updated. However, the field stays null.

// test class
Apple apple = Mock(Apple.class)

myService.myMethod(apple)

assert apple.color == Color.RED //FAIL because apple.color == null 
// tested code of myMethod(Apple apple) 
apple.color = Color.RED

Solution

  • Tim and Szymon are both right. When using a mock, you should not be surprised to get mock results, i.e. null.

    I understand that to unit-test MyService in isolation, you want to mock Apple. But then, please verify an interaction on the setter rather than implicitly calling the getter and expecting a non-null result.

    package de.scrum_master.stackoverflow.q78458317
    
    import spock.lang.Specification
    
    import java.awt.*
    
    class MyServiceTest extends Specification {
      def test() {
        given:
        def myService = new MyService()
        Apple apple = Mock(Apple)
    
        when:
        myService.myMethod(apple)
    
        then:
        1 * apple.setColor(Color.RED)
      }
    }
    
    class Apple {
      Color color
      boolean isFresh
    }
    
    class MyService {
      void myMethod(Apple apple) {
        apple.color = Color.RED
      }
    }
    

    Try it in the Groovy Web Console.