开发者

How To Mock Out A Closure In Order To Test The Grails Service Result?

I want to unit test the return value of some code which looks similar to this:

Groovy Service code to test:
    def findByThisAndThat(something) {
            : 
        def items = []
        sql.eachRow(query, criteriaList, {
            def item = new Item(name:it.NAME)
            items.add(item)
        })
        [items: items, whatever:whatevervalue]
    }

Unit test code plan:

   void testFindByThisAndThatReturnsAMapContainingItems(){
       Sql.meta开发者_StackOverflowClass.eachRow = { String query, List criteria, Closure c ->

           // call closure to get passed in items list
           // add one new Item(name:"test item") to list
       }

       def result = service.findByThisAndThat("", "")

       assert result.items
       assertEquals('test item', result.items[0].name)
   }

How can I do that? Thanks!


A unit test like you're proposing really just tests that given proper data from the database, you assemble it correctly into Item instances. I'd switch instead to an integration test where you have access to a real database and test the whole method with test data in the db.

Unit testing database access typically is more of a test of the mocking code than of your code, so it's often of little use.


Call the closure by using it like a method. Alternatively, you can use Closure.call() as well. Pass in the value for it as the first parameter.

Sql.metaClass.eachRow = { String query, List criteria, Closure c ->
    def mockItems = ["test item"]
    mockItems.each { item ->
        c(item)
        // c.call(item) works too
    }
}

Note that the Sql metaClass won't get reset at the end of the test. I'd recommend clearing it out after the test:

Sql.metaClass = null
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜