Как смоделировать замыкание, чтобы проверить результат обслуживания Grails? - PullRequest
3 голосов
/ 20 января 2011

Я хочу провести модульное тестирование возвращаемого значения некоторого кода, который выглядит примерно так:

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]
    }

План кодов модульных испытаний:

   void testFindByThisAndThatReturnsAMapContainingItems(){
       Sql.metaClass.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)
   }

Как я могу это сделать? Спасибо!

Ответы [ 2 ]

2 голосов
/ 20 января 2011

Модульный тест, который вы предлагаете на самом деле просто тесты, которые дают правильные данные из базы данных, вы правильно собираете в экземпляры Item. Вместо этого я бы переключился на интеграционный тест, где у вас есть доступ к реальной базе данных, и протестировал весь метод с тестовыми данными в БД.

Модульное тестирование доступа к базе данных, как правило, является скорее проверкой кода-насмешки, чем вашего кода, поэтому он часто бесполезен.

1 голос
/ 20 января 2011

Вызовите замыкание, используя его как метод.Также вы можете использовать Closure.call().Передайте значение для it в качестве первого параметра.

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

Обратите внимание, что метакласс Sql не будет сброшен в конце теста.Я бы порекомендовал очистить его после теста:

Sql.metaClass = null
...