Search code examples
grailsgroovymocking

Grails Mocking: Supply any argument to demand closure


I have a service that I'm trying to test. Inside this service is another UserAPIService that I want to mock. To mock it I'm doing the following:

    given:
    def userAPIServiceMock = mockFor(UserAPIService)
    userAPIServiceMock.demand.createUser { def apiToken, firstname, lastname, email -> return true 
    }
    service.userAPIService = userAPIServiceMock.createMock()

In the demand closure, I don't really care what arguments are passed to the createUser method. Is there a way I can say "regardless of the arguments passed to the createUser method, return true."

In other words, how can I change

userAPIServiceMock.demand.createUser { def apiToken, firstname, lastname, email -> return true 

to

userAPIServiceMock.demand.createUser { [any arguments] -> return true 

Solution

  • This is possible with Spock.

    The syntax is as follows:

    mock.method(*_) >> { args -> true }
    

    Not sure how your Grails service needs to be mocked, but here's a full, general example in Spock:

      interface Service {
        boolean hej( String s, boolean b, char c )
      }
    
      class ExampleSpec extends Specification {
    
      def "mock method with any number of args"() {
        when:
        def mock = Mock( Service )
        mock.hej(*_) >> { args -> true }
    
        then:
        mock.hej( 'hi', true, 'a' as char ) == true
      }
    }
    

    args is a List containing the actual arguments, which you can inspect in the closure and return the appropriate value.