2

we are preparing for Grails 2.4 upgrade. One of the issues we face is that most of the command object unit tests fails because of injected properties, like services, are required to be not null during validation.

Is there any suggested way how to test this? Should we mock all properties although some are not needed for test? or is there a way to do this differently?

After my question is answered by Jeff, I share links with more information about new functionalities: doWithSpring and doWithConfig are shortly described in What's new in 2.4: http://grails.org/doc/latest/guide/introduction.html#whatsNew24 in Unit Testing improvements section There is also a JIRA issue with example: https://jira.grails.org/browse/GRAILS-11003

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
practical programmer
  • 1,604
  • 10
  • 15
  • 1
    @danielad: please don't add code spans (`like this`) for emphasis. See [this Meta post](http://meta.stackexchange.com/a/165710) for more information. – Qantas 94 Heavy Aug 04 '14 at 09:01

1 Answers1

3

Most unit tests don't want or need the application context all spun up and populated. Unit tests can add whatever they want (or nothing) to the application context. In recent versions of Grails you can do something like this...

A controller and command object:

// grails-app/controllers/demo/DemoController.groovy
package demo

class DemoController {

    def processName(SomeCommand co) {
        render co.someValue
    }
}

class SomeCommand {
    String name
    def helperService

    def getSomeValue() {
        helperService.processValue(name)
    }
}

A service:

// grails-app/services/demo/HelperService
package demo

class HelperService {

    def processValue(String originalValue) {
        "__${originalValue}__"
    }
}

A unit test:

// grails-app/test/unit/demo/DemoControllerSpec.groovy
package demo

import grails.test.mixin.TestFor
import spock.lang.Specification

@TestFor(DemoController)
class DemoControllerSpec extends Specification {

    def doWithSpring = {
        helperService HelperService
    }

    void 'process name'() {
        when:
        params.name = 'Jeff'
        controller.processName()

        then:
        response.contentAsString == '__Jeff__'
    }
}

That test will pass with Grails 2.4.2.

I hope that helps.

Jeff Scott Brown
  • 26,804
  • 2
  • 30
  • 47
  • Of course if the unit test wanted to add a fake version of `helperService` to the context, that would be fine. Instead of `helperService HelperService` in the `doWithSpring` block you could do something like `helperService MyFakeHelperService`. – Jeff Scott Brown Jul 19 '14 at 14:38
  • Thank you Jeff. `doWithSpring` answers my questions – practical programmer Jul 19 '14 at 16:16
  • Great. I could have just described doWithSpring but I think a simple but complete example often is the best way to present something like that. Glad you are all set. – Jeff Scott Brown Jul 19 '14 at 16:55