Grails unit testing for beginners

14 / Jul / 2010 by Imran Mir 0 comments

Ques: How is unit testing different from integration testing ?

Ans: Integration tests need to bring up the whole grails environment.They talk to the database. All the dynamic GORM methods and properties are available here. Unit testing are small focused, fast loading tests that do not load supporting components.

Ques: How can I unit test a method in a service ?

Ans: You would need to follow these simple steps:

Suppose you want to write a unit test case for a someFunction() in MyService:

class MyService {
    public String myFunction() {
      return "testString"

-> Create Unit Test File : grails create-unit-test It will create the test file in the folder /test/unit
-> Write a testcase function
-> Create an object of MyService
-> Call the function and make assertions

public void testMyFunction() {
    def myService = new MyService()
    String string = myService.myFunction()
    assertEquals "testString", string

Ques: I am saving an object from this function. How can I test that ?

 public void myFunction(int number, String name) {
    MyDomainClass object = new MyDomainClass(age: number, name: name)

Ans: Its pretty simple. You would first need to mock the domain class whose object is being saved.

   def instances = []
   def myTestDomain = mockDomain('MyDomainClass',instances)

instances will serve as a cache of objects. Right now it contains no object. But when you call the save method from the function to be tested, it will automatically put that object in this cache. So, we can make assertions against this cache. Just to remind you, no database communication occurs during the unit testing.

 public void testMyFunction() {
    def instances = []
    def myTestDomain = mockDomain('MyDomainClass', instances)
    def myService = new MyService()
    String string = myService.myFunction(30, 'myName')
    assertEquals 1, instances.size()

Ques: What does this mockDomain do ?

Ans: mockDomain is a method of GrailsUnitTestCase, that helps to mock a domain class. mockDomain also mocks most of the injected methods of the domain class like, save(), validate(),delete(),get() and many others. But there are many methods it does not mock,e.g., createCriteria,find,findAll,withTransaction and many others.

Ques: That was great. But now my function uses some other service to do some job. How can I test that ?

  public void myFunction(String empId) {
    String name = otherService.someOtherFunction(empId)
    MyDomainClass object = new MyDomainClass(name: name)

Ans: In this case you would need to mock both, other service as well as the method which is called.

void testMyFunction() {
    def otherService = mockFor(OtherService)
    otherService.demand.someOtherFunction() {empId-> return "testName"}
    def myService = new MyService()
    myService.otherService = otherService.createMock()
    String string = myService.myFunction(30, 'myName')
    assertEquals 1, instances.size()

Ques: What does this mockFor method do ?

Ans: It is a method that is used to mock a dependency. We can mock services and its methods with the help of this. The demand method of the object returned by the method can be used to mock different methods of the mockedInstance. We can also specify the number of times the function is actually called in the function.

 otherService.demand.someOtherFunction(1..2) {empId; return "testName"}

Here, it means someOtherFunction() will be called not more than 2 times in the function.

Hope this helps.
Imran Mir


Leave a Reply

Your email address will not be published. Required fields are marked *