groovy/grails/unittesting/createCriteria.get

groovy/grails/unittesting/createCriteria.get,grails,groovy,mocking,hibernate-criteria,Grails,Groovy,Mocking,Hibernate Criteria,我可以模拟呼叫: MyDomainClass.createCriteria().list{ eq('id',id) eq('anotherParameter',anotherParameterId) } 与: 通知如下: 但对于: MyDomainClass.createCriteria().get{ eq('id',id) eq('anotherParameter',anotherParameterId) } 这种方法失败了——可能是因为“get”是一个关

我可以模拟呼叫:

MyDomainClass.createCriteria().list{
    eq('id',id)
    eq('anotherParameter',anotherParameterId)
}
与:

通知如下:

但对于:

MyDomainClass.createCriteria().get{
    eq('id',id)
    eq('anotherParameter',anotherParameterId)
}
这种方法失败了——可能是因为“get”是一个关键字,而“list”不是。任何人都可以建议-能够在域类中模拟这一点应该是可能的,而不必简单地放弃使用
createCriteria().get{}
的方法的单元测试覆盖率

非常感谢您的建议


亚历克斯

我不想麻烦了。而是在域类中创建方法并模拟这些方法。这使得测试更容易,但更重要的是,它的优点是保持持久性,而不是将持久性分散在整个代码库中:

class MyDomainClass {
   String foo
   int bar

   static MyDomainClass findAllByIdAndAnotherParameter(long id, long anotherParameterId) {
      createCriteria().list {
         eq('id',id)
         eq('anotherParameter',anotherParameterId)
      }
   }

   static MyDomainClass getByIdAndAnotherParameter(long id, long anotherParameterId) {
      createCriteria().get {
         eq('id',id)
         eq('anotherParameter',anotherParameterId)
      }
   }
}
然后在测试中,只需将其模拟为

def testInstances = [...]
MyDomainClass.metaClass.static.findAllByIdAndAnotherParameter = { long id, long id2 ->
   return testInstances
}


我已经找到了一个不会影响我编写单元测试能力的解决方案-

def myCriteria = new Expando();
myCriteria .get = {Closure  cls -> returnThisObject}         
MyDomainClass.metaClass.static.createCriteria = {myCriteria }

这正是我想要的,并且可能支持测试提供的参数。谢谢你的回复。希望这对其他测试domain/createCriteria()方法有用。

现在使用
GrailsUnitTestCase.mockDomain
方法应该简单得多

grails-app/domain/sandbox/grails/foo/Something.groovy test/unit/sandbox/grails/foo/SomethingTests.groovy
我已将其简化为以下内容:String hello=“hello”def map=[get1:{Closure cls->hello},address:“某处”]打印map.get1{}String hello=“hello”def map=[get:{Closure cls->hello},address:“某处”]打印map.get{}区别在于当map键为“get1”时,打印map.get1{}打印“hello”,但当密钥为“get”时,则返回null。也许“get”是一种语言冲突,所以我需要一种完全不同的方法来模拟createCriteria().get{}。这是一种比第一种更好、更干净的解决方案,因为从Grails 2.0开始,域类应该只知道其中的内部结构,而不是客户端,但我确实记得在1.8.x中也使用过它。
def testInstance = new MyDomainClass(...)
MyDomainClass.metaClass.static.getByIdAndAnotherParameter = { long id, long id2 ->
   return testInstance
}
def myCriteria = new Expando();
myCriteria .get = {Closure  cls -> returnThisObject}         
MyDomainClass.metaClass.static.createCriteria = {myCriteria }
package sandbox.grails.foo

class Something {
    String name
}
package sandbox.grails.foo

import grails.test.mixin.*
import org.junit.*

@TestFor(Something)
class SomethingTests {

    void testSomething() {

        mockDomain(Something, [
            new Something(name: 'Foo'),
            new Something(name: 'Bar'),
            new Something(name: 'Boo'),
            new Something(name: 'Baz')
        ])

        def actuals = Something.createCriteria().list(sort: 'name', order: 'asc') {
            like('name', '%oo')
        }

        assertEquals 2, actuals.size()

    }
}