Details
Description
I have this method in a controller:
def show = {
def profile
if (params.username) {
profile = profileService.getPublicProfileForUser(params.username)
}
if (!profile) {
response.sendError(404)
return;
}
[profile: profile]
}
The method works when browsing on the site following grails run-app
I've also written a unit test extending ControllerUnitTestCase:
void testShowWithUser() {
def profileServiceControl = mockFor(ProfileService)
profileServiceControl.demand.getPublicProfileForUser(1) {
new PublicProfile()
}
controller.profileService = profileServiceControl.createMock()
controller.params.username = 'viewedUser'
controller.show()
assertEquals "Wrong view", "show", controller.modelAndView.view
assertNotNull "Missing profile in returned model", controller.modelAndView.model.profile
profileServiceControl.verify()
}
The test fails for both assertions after grails test-app, ie the view name is not set and the model is not populated.
Changing the last line of the controller show() method to the following allows the test to pass:
render view: "show", model: [profile: profile]
So it's not possible to test model and view without explicitly setting the view in a render statement.
I think that your test should do something like this...
import grails.test.* class DemoControllerTests extends ControllerUnitTestCase { void testShowWithUser() { def profileServiceControl = mockFor(ProfileService) profileServiceControl.demand.getPublicProfileForUser(1) { new PublicProfile() } controller.profileService = profileServiceControl.createMock() controller.params.username = 'viewedUser' def model = controller.show() assertNotNull "Missing profile in returned model", model.profile profileServiceControl.verify() } }That will assert that a model was returned (render was not called) and that the model contains a profile.
Is that what your test should be doing?
On an unrelated note... in your unit test you don't really need to mock out your ProfileService, you could just plug in a fake like a Map if you wanted. I don't think that is relevant to your real question though...
import grails.test.* class DemoControllerTests extends ControllerUnitTestCase { void testShowWithUser() { controller.profileService = [getPublicProfileForUser: { 'dummy user'}] controller.params.username = 'viewedUser' def model = controller.show() // just make sure the model includes whatever the profileService returned... assertEquals 'Wrong profile in returned model', 'dummy user', model.profile } }import grails.test.* class DemoControllerTests extends ControllerUnitTestCase { void testShowWithUser() { def profileServiceControl = mockFor(ProfileService) profileServiceControl.demand.getPublicProfileForUser(1) { new PublicProfile() } controller.profileService = profileServiceControl.createMock() controller.params.username = 'viewedUser' def model = controller.show() assertNotNull "Missing profile in returned model", model.profile profileServiceControl.verify() } }import grails.test.* class DemoControllerTests extends ControllerUnitTestCase { void testShowWithUser() { controller.profileService = [getPublicProfileForUser: { 'dummy user'}] controller.params.username = 'viewedUser' def model = controller.show() // just make sure the model includes whatever the profileService returned... assertEquals 'Wrong profile in returned model', 'dummy user', model.profile } }