Interaction based testing using Spock in Grails
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
[java]
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()}")
}
}
}
[/java]
and you have a method which calls this method
[java]
class UserService {
def emailService
void sendActivationMail(User user){
emailService.sendMail(user.email,"admin@admin.com","Your account is activated", "Congratulation now you can login")
}
}
[/java]
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
[java]
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")
}
[/java]
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
could you please teel me how i can use debugger while running unit test cases.