Search code examples
javagroovyspock

Can I add a delay to a call to a Stub method in Spock?


I'm using the Spock Framework to test some Java classes. One thing I need to do is add a delay to a Stub method that I'm calling, in order to simulate a long-running method. Is this possible?

This looks possible using Mockito: Can I delay a stubbed method response with Mockito?. Is it possible using Spock?


Solution

  • Spock is a Groovy tool. Therefore, you have some syntactic sugar and do not need a tedious try-catch around Thread.sleep. You simply write:

    // Sleep for 2.5 seconds
    sleep 2500
    

    Your test could look like this:

    class Calculator {
      int multiply(int a, int b) {
        return a * b
      }
    }
    
    class MyClass {
      private final Calculator calculator
    
      MyClass(Calculator calculator) {
        this.calculator = calculator
      }
    
      int calculate() {
        return calculator.multiply(3, 4)
      }
    }
    
    import spock.lang.Specification
    
    import static java.lang.System.currentTimeMillis
    
    class WaitingTest extends Specification {
      static final int SLEEP_MILLIS = 250
    
      def "verify slow multiplication"() {
        given:
        Calculator calculator = Stub() {
          multiply(_, _) >> {
            sleep SLEEP_MILLIS
            42
          }
        }
        def myClass = new MyClass(calculator)
        def startTime = currentTimeMillis()
    
        expect:
        myClass.calculate() == 42
        currentTimeMillis() - startTime > SLEEP_MILLIS
      }
    }
    

    Try it in the Groovy web console.