Tropical Software Observations

09 January 2009

Posted by Teo Choong Ping

at 5:31 PM

4 comments

Labels: ,

Testing Grails Service class

Testing Grails service classes is easy if the service does not call any domain persistence methods. Meaning if your service class does cause some domain object to persist to database, it's going to be painful to try to mock the calls and check the result. And I'm not even sure if it's worth it to try.

The problem is that grails-testing newbies like me will want to try to do unit testing for services. In short, don't do that unless your service classes are simple and easy. (Keep this in mind when you start your project -- you won't see this unless you've experienced the pain before).

The best way that I found so far is to make service tests into integration tests. This mean putting service tests into the "integration" folder under the test directory. For more explanation on the difference between Unit Testing and Integration Testing in Grails, go here.

Testing Service classes is easy once you understand that it is:

  • it is an integration test -- will talk to the database
  • it is slow -- probably because of the data connection overhead
  • will persist data to database -- make sure your test environment database settings don't point to a production database
A typical service test looks like this:
class FooServiceTests extends GroovyTestCase {

def fooService

void setUp() {
fooService = new FooService // *1
fooService.otherService = new OtherService() // *2
}


void testServiceCall() {
def user = new User(name:"Test", email:"test@name.com")
user.save(flush:true) // *3
fooService.doSomething(user) // *4
assertEquals user.result, "expected result"
}

}
A couple of helpful points as indicated by the numbers above:
  1. You have to initialize the service class yourself, there is no DI.
  2. If the service has other service classes inside it, initialize and assign it manually
  3. Remember to always flush to persist to the database immediately -- else you might get weird things like no "id" for the supposedly saved domain object.
  4. In integration mode, fooService will act like a "headless" Grails app

I hope this is helpful to you -- I may not be right, so feedback and corrections are welcomed.

4 comments:

Daniel K said...

Might try the testing-plugin or use a beta version of Grails 1.1 which has this plugin integrated, because it pretty much mocks the data access for you without relying on slow integration tests.

This means you can do fast unit testing with your service classes.

shitmores said...

Testing plugin was one of the thing I tried for unit testing -- not a bed or roses.

I'm still looking for more effective ways of testing service as unit test.

Riada Endo said...

Test the system or the product must every company. As one of the top ten our company Nix Solution that take major place in the are of software web and mobile development understand that more than everyone else http://www.nixsolutions.com/services/quality-assurance-services/ . And because of that we introduce assurance service that cover every our project.

Emma Johanson said...

Thank you! Very interesting. But, actually I don't understand everything, because I am not good in this field ) Yesterday I found this software testing company http://qatestlab.com/services/special-offer/game-testing/ I guess, it's a professionals and I am going to use their services.