Search code examples
unit-testinggrailsmockinggrails-orm

Mocking domain classes in Grails


I've got a set of domain and controller classes called: Organization and OrganizationController respectively.

THe OrganizationController only has one method:

def index() {
    def organizations = Organization.list()
    [orgs: organizations]
}

I've tried to mock out the Domain class by 2 ways.

The first way was using the @Mock annotation, and creating the objects and saving:

void "test index"() {
    given:
    new Organization(name: 'JIMJIM').save()
    new Organization(name: 'ABC').save()

    def expected = [org: [new Organization(name: 'JIMJIM'),
                    new Organization(name: 'ABC')]]

    when:
    def actual = controller.index()

    then:
    actual == expected
}

That caused Oraganization.list to return an empty list. Actual returns [org: []]

I also tried using mockDomain:

void "test index"() {
    given:
      mockDomain(Organization, [new Organization(name: 'JIMJIM'),
                              new Organization(name: 'ABC')
     ])

    def expected = [org: [new Organization(name: 'JIMJIM'),
                    new Organization(name: 'ABC')]]

    when:
    def actual = controller.index()

    then:
    actual == expected
}

However I still got the same result. Why is it that my domain classes are not getting mocked?

My test decoration (OrganizationControllerSpec) is the following:

@TestFor(OrganizationController)
@Mock(Organization)
@TestMixin(DomainClassUnitTestMixin)
class OrganizationControllerSpec extends Specification {

I'm using Grails 2.3.8.


Solution

  • The first snippet seems to be ok, but...

    First of all, were the Organization objects actually created? Are all required fields provided? Please, try using save(failOnError: true) to make sure.

    Moreover, in controller you have orgs, while you use org in the test. Is it only a misspell?

    Also, unless you have equals method overwritten in Organization class, the objects from database are not equal to the ones you create with new operator.