Groovy has some great support for testing, including:
- GroovyTestCase (which extends on JUnit)
- Testing for exceptions via "shouldFail()"
- First-class mocking support built-into the language
In Grails when you create a controller, domain, job, or service it will automatically create a test class for it. However it creates them all as integration tests which run slower than unit tests because the entire Grails environment needs to get bootstrapped to success run the tests. I can understand testing the domain classes as integration tests because they need to hit the database.
Most of the code that I'm going to write should be in the service layer. So I need the service layer tests to run quickly so I can get a quick feedback. Lucky Groovy makes it pretty easy for me to mock out the domain layer in my service tests. Below is an example of a service layer test that mocks out the "Site" domain object:
void testAccessDataObject() {
def service = new SampleService()
def siteMock = new groovy.mock.interceptor.StubFor(Site)
siteMock.demand.get {id ->
return new Site()
}
siteMock.demand.getName {id ->
return 'my sample site'
}
def results
siteMock.use {
results = service.accessDataObject()
assertEquals 'my sample site', results.name
}
}
Currently I am on the fence on whether controllers should be written as unit or integration tests. I am leaning towards integration tests because I will be able to write a test that tests the entire mvc stack. What are your thoughts on testing the controller?
Just a little tip for running test with grails. Normally you run the "grails test-app" command to run both the unit and integration tests. If you just want to run the unit tests you can run "grails test-app -unit" and just the integration tests with "grails test-app -integration".
There's a Grails plugin to integrate Canoo Webtest to able to write functional tests (aka user acceptance tests). You can write your functional tests in Groovy instead of xml if you desire. I haven't tried it yet, but there's also a plugin for integrating Cobertura test coverage tool.
Because of Groovy and Grails excellent testing support I would be a fool to write Siteproducer without testing. I can't guarantee 100% test coverage, but at least 60% would be great.
2 comments:
I think the integration testing is actually a very cool idea. It should really help with the regression testing every time code changes and helps minimize any logic/functional errors introduced in related modules by code changes.
As you mentioned above, the integration test will be slower. I would suggest writing a unit test instead of a narrow or focused integration test for your service. If you use a continuous integration server and run all tests as part of the build every time someone commits, you'll see that the slower tests will start causing you grief.
Furthermore, the integration tests have more value when they encompass a larger part of the system (the famous end-to-end testing).
Post a Comment