【问题标题】:How To Mock Out A Closure In Order To Test The Grails Service Result?如何模拟闭包以测试 Grails 服务结果?
【发布时间】:2011-06-12 04:05:20
【问题描述】:

我想对一些类似这样的代码的返回值进行单元测试:

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

我该怎么做? 谢谢!

【问题讨论】:

    标签: testing grails groovy mocking metaclass


    【解决方案1】:

    像您提议的单元测试实际上只是从数据库中给出适当数据的测试,您将其正确组装到 Item 实例中。我会改用集成测试,您可以在其中访问真实数据库并使用数据库中的测试数据测试整个方法。

    对数据库访问进行单元测试通常更多的是对模拟代码的测试,而不是对您的代码的测试,因此它通常没有什么用处。

    【讨论】:

      【解决方案2】:

      通过像方法一样使用它来调用闭包。或者,您也可以使用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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 1970-01-01
        • 2019-12-21
        • 1970-01-01
        相关资源
        最近更新 更多