Armand
Armand

Reputation: 24353

What are the restrictions of Grails' mockDomain() method?

I'm writing a Spock Spec (unit test) for a Service in Grails 1.3.5, and I've run across the following error:

No signature of method: myapp.Thing.findAll() is applicable for argument types: (java.util.LinkedHashMap) values: [[sort:index, order:asc]] Possible solutions: findAll(), findAll(groovy.lang.Closure), find(groovy.lang.Closure), getAll(java.util.List), getAll([Ljava.lang.Object;)

groovy.lang.MissingMethodException: No signature of method: myapp.Thing.findAll() is applicable for argument types: (java.util.LinkedHashMap) values: [[sort:index, order:asc]]
Possible solutions: findAll(), findAll(groovy.lang.Closure), find(groovy.lang.Closure), getAll(java.util.List), getAll([Ljava.lang.Object;)
    at grails.test.MockUtils.addDynamicFinders_closure56(MockUtils.groovy:641)
    at myapp.MyService.getCards(MyService.groovy:8)
    at myapp.MyServiceSpec.getCards returns empty map if no cards or statuses are available(MyServiceSpec.groovy:13)

Previously this test passed, but the failure occurred when I modified my Service to include sorting of results in the getThings() method.

class MyService {
    static transactional = true

    static getThings() {
        Thing.findAll(sort: 'index', order: 'asc')
    }
}

This still appears to work when the application is run, so I suspect it's a limitation of the implementation of mockDomain().

class MyServiceSpec extends UnitSpec {
    def 'mockDomain has some limits, i suspect'() {
        given:
            mockDomain(Thing)
            def myService = new MyService()
        when:
            myService.getThings()
        then:
            true
    }
}

So my question is are their differences in the methods added to a domain class using mockDomain() as opposed to using the real domain class at runtime? If so, what are they?

Upvotes: 3

Views: 5714

Answers (2)

Victor Sergienko
Victor Sergienko

Reputation: 13475

sort and order are Hibernate criteria parameters, they won't work with MockDomain() - it doesn't involve Hibernate. Luckily.

You can mock that findAll() signature yourself, using instances array - the second parameter of MockDomain(), (EDIT) like, this overrides findAll(Map) signature of Thing:

List<Thing> thingInstances = []

void setUp() {
    mockDomain(Thing, thingInstances)

    Thing.metaClass.`static`.findAll = { Map m ->
        def result = thingInstances.sort{ it."${m.order}" }
        m.order == 'asc' ? result : result.reverse()
    }
}

(EDIT end)

Or you can make it integration test, then it will run for ages. Which I don't recommend.

Upvotes: 3

Stefan Armbruster
Stefan Armbruster

Reputation: 39915

There is a new approach for mocking domain objects: http://grails.1312388.n4.nabble.com/New-approach-to-mocking-domain-classes-in-Grails-unit-tests-td2529895.html. Maybe this helps you out here.

Upvotes: 1

Related Questions