I've recently upgraded a Grails 1.3.7 project up to Grails 2.0.4 and noticed that many of my unit tests with mocking have started to fail. The Controller tests seem to pass just fine, the issue comes when you have Services collaborating with one another and try to mock out the calls to the collaborators. The strange part about it is if I run the single test, it passes, but as soon as I run the entire suite, they fail giving the error:
No more calls to 'getName' expected at this point. End of demands.
junit.framework.AssertionFailedError: No more calls to 'getName' expected at this point. End of demands.
I've even tried using GMock instead of new MockFor(), but get this very similar error:
No more calls to 'getSimpleName' expected at this point. End of demands.
junit.framework.AssertionFailedError: No more calls to 'getSimpleName' expected at this point. End of demands.
Here's a contrived example showing how to duplicate the errors I'm getting, and the entire sample project on GitHub at https://github.com/punkisdead/FunWithMocks. Any ideas of how to make this work?
BarController:
package funwithmocks
class BarController {
def barService
def fooService
def index() { }
}
BarService:
package funwithmocks
class BarService {
def fooService
def bazService
def serviceMethod() {
}
}
BarControllerTests:
package funwithmocks
import grails.test.mixin.*
import org.junit.*
import groovy.mock.interceptor.MockFor
/**
* See the API for {@link grails.test.mixin.web.ControllerUnitTestMixin} for usage instructions
*/
@TestFor(BarController)
class BarControllerTests {
def fooService
def barService
@Before
public void setUp() {
fooService = new MockFor(FooService)
fooService.use {
controller.fooService = new FooService()
}
barService = new MockFor(BarService)
barService.use {
controller.barService = new BarService()
}
}
@Test
void doSomething() {
controller.index()
}
}
BarServiceTests: package funwithmocks
import grails.test.mixin.*
import org.junit.*
import groovy.mock.interceptor.MockFor
/**
* See the API for {@link grails.test.mixin.services.ServiceUnitTestMixin} for usage instructions
*/
@TestFor(BarService)
class BarServiceTests {
def fooService
def bazService
@Before
public void setUp() {
fooService = new MockFor(FooService)
fooService.use {
service.fooService = new FooService()
}
bazService = new MockFor(BazService)
bazService.use {
service.bazService = new BazService()
}
}
@Test
void callSomeService() {
service.serviceMethod()
}
}
You shouldn't to combine the new test mixin with MockFor
groovy class. Replace all MockFor
instance with the mockFor
method.
http://grails.org/doc/latest/guide/testing.html#mockingCollaborators