Interaction based testing using Spock in Grails

07 / Apr / 2011 by Uday Pratap Singh 1 comments

In my recent project we are using spock test cases to test our application and spock really made it easy for us to test those things we were not able to test in Grails Unit Test or testing such things dont look so intuitive in Grails Unit tests . One of the powerful method of spock testing is interaction based testing, which allow us to test whether the call is made to some other method with the defined parameters and it also tests how many calls are made to the other method.

The email sending perfectly fits into this example. So you have mail sending plugin in your application and one of your method sends mail to the users like following

class EmailService {
def asynchronousMailService

public sendMail(String to, String from, String subject, String body) {
    try {
      asynchronousMailService.sendAsynchronousMail {
        to to
        subject subject
        body to
        from from
      }
    }
    catch (Throwable t) {
      log.error("Exception while sending email to user ${to}, Exception is ${t.getStackTrace()}")
    }
  }
}

and you have a method which calls this method

class UserService {

def emailService

void sendActivationMail(User user){
    emailService.sendMail(user.email,"admin@admin.com","Your account is activated", "Congratulation now you can login")

  }

}

Now when you are testing sendActivationMail method you would like to can verify whether the call is made to emailService or not by using spock interaction based testing. You will write your test case something like

def "account activation mail sent to user"(){
setup:
UserService userService = new UserService()

def emailService = Mock(EmailService)  // As we are not testing email service, we mocked the emailService 
emailService.sendMail(_,_,_,_) >> true  //This will ensure to return true for any argument passed for sendMail method 
userService.emailService = emailService

User user = new User(email : "testUser@gmail")

when:
userService.sendActivationMail(user)

then:
1*emailService.sendMail("testUser@gmail","admin@admin.com","Your account is activated", "Congratulation now you can login")

}

The then block ensures that the exactly 1 call is made to sendMail method with exactly the same arguments.
We can have other use cases for interaction based testing like making calls to external APIs, logging different statements in different conditions.

Hope it helps
Uday Pratap Singh
uday@intelligrape.com

FOUND THIS USEFUL? SHARE IT

comments (1 “Interaction based testing using Spock in Grails”)

Leave a comment - shubham Cancel reply