模拟标准计算api grails / groovy

时间:2013-04-24 15:46:23

标签: grails groovy mocking

我在尝试对服务类api进行单元测试时遇到问题

MyService.groovy

public int myMethod() {
  def cr = MyDomain.createCriteria()

  def myDomainCount = cr.count {
    isNull("column1")
  }

  return myDomainCount
}

MyTestClass.groovy

class MyTestClassTests extends GrailsUnitTestCase {

  void testMyCount() {

    mockDomain(MyDomain)

    myCriteria = [count :{Closure cls -> 10}]
    MyDomain.metaClass.static.createCriteria = {myCriteria}

    int cnt = new MyService().myMethod()

    assert 10 == cnt
  }
}

执行myMethod()时执行上述测试方法失败。它失败了

cr.count {
  isNull("column1")
}

我在执行过程中得到的堆栈跟踪:

groovy.lang.MissingMethodException: No signature of method: com.MyService.isNull() is applicable for argument types: (java.lang.String) values: [column1]
 Possible solutions: findAll(), findAll(groovy.lang.Closure), is(java.lang.Object), isCase(java.lang.Object) at
 org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:55) at 
 org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:78) at
 org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:49)

注意:如果我在地方(服务类和测试类)中都使用cr.list,那么相同的测试用例可以正常工作。我不知道为什么它在计数期间失败????? !!!!

任何想法都会有很大的帮助。谢谢。

1 个答案:

答案 0 :(得分:0)

解决这个问题的两种方法:

1 - 只需创建实例

由于您可以模拟您的域类,因此请创建与您的服务查询匹配的实例。

@TestFor(MyService)
@Mock(MyDomain)
class MyServiceTests {
  void testService() {
    MyDomain instance = new MyDomain(...)
    assert instance.save(flush:true)
    def count = service.myMethod()
    assert 1 == count
  }
}

2 - 模拟grails.gorm.CriteriaBuilder

createCriteria()返回grails.gorm.CriteriaBuilder的实例,您可以使用Groovy MockFor更改count{}的行为。

@TestFor(MyService)
@Mock(MyDomain)
class MyDomainServiceTests {

  void testWithGroovyMock() {
    def mockedCriteria = new MockFor(CriteriaBuilder)
    mockedCriteria.demand.count(0..999) { Closure cls ->
      return 10
    }

    def count

    mockedCriteria.use {
      count = service.countWithIsNull()
    }

    assert 10 == count

  }

}

您可以找到有关Groovy MockFor here的更多信息。

另请注意,我使用Grails 2.x方式声明单元测试(注释)。