尝试对服务类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")
}
我在执行过程中得到的stacktrace:
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-仅创建实例
由于可以模拟域类,因此可以创建与您的服务查询匹配的实例。
@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声明单元测试(注释)的方法。
关于grails - 模拟标准计数api grails/groovy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16196448/