Gregg
Gregg

Reputation: 35864

Asserting view with Grails Spock Unit Test for Controllers

I'm trying to test that the correct view is rendered from a grails controller. My create method looks like this:

def create() {
    def documentCategories = DocumentCategory.list()
    def documentTypes = DocumentType.list()
    def documentComponents = DocumentComponent.list()
    [documentCategories: documentCategories,
        documentTypes: documentTypes,
        documentComponents:documentComponents]
}

And my test:

def "test create action"() {
    given:
    def model = controller.create()

    expect:
    response.status == 200
    model.documentCategories.size() == 0
    model.view == '/document/create'
}

I've tried various versions of model.view including:

view == '/document/create'
response.forwardedUrl == '/document/create'

all of which fail because model.view, view, and response.forwardedUrl are all null. Suggestions?

Upvotes: 3

Views: 3387

Answers (3)

Raipe
Raipe

Reputation: 807

As you are not defining the view explicitly in the controller method then the Grails conventions will take place. Accordingly to documentation a view matching the name of the controller and method will be chosen --> view: "controllerName/methodName"

Regarding your problem, you should not be testing that the Grails framework is working. You should be testing that your controller behaves as you want.

In this case you want to test that your controller does not specify the view as that is the expected behavior of your controller.

Test for this would be:

   then:
    controller.modelAndView == null
    response.redirectedUrl == null

As the modelAndView will be created if you would call the 'render(view: xxx)' in your controller.

Calling redirect() or chain() in your controller results to response.redirectedUrl to be populated in your unit test

Upvotes: 4

dmahapatro
dmahapatro

Reputation: 50245

view.endsWith('/document/create')

should work provided view and model is explicitly rendered from the controller.

//controller
render view: 'create', model: [documentCategories: documentCategories,
                               documentTypes: documentTypes,
                               documentComponents:documentComponents]

In case of JUnit tests the explicit mention of view and model is optional, but for Spock spec it is required.

Upvotes: 1

Alex Blakemore
Alex Blakemore

Reputation: 11896

Try adding the following to your test as specified in the Grails Test docs

import grails.test.mixin.TestFor
@TestFor(MyController)

Upvotes: 0

Related Questions