Unit testing 为单元测试扩展Grails模拟(createCriteria、withNewSession等)

Unit testing 为单元测试扩展Grails模拟(createCriteria、withNewSession等),unit-testing,grails,groovy,Unit Testing,Grails,Groovy,作为Grails项目的一部分,我目前正在扩展我的测试套件,以满足需要一个完整环境才能运行的需求,例如自定义HQL和条件查询、会话相关问题等。我正在使用集成测试 我们已经有了相当多的单元测试(>500),在这些单元测试中,我们使用如下辅助函数来模拟默认情况下没有Grails模拟对应项的方法(如withCriteria,withNewSession,等等): static mockCriteria(Class clazz, returnValue) { def myCriteria = new

作为Grails项目的一部分,我目前正在扩展我的测试套件,以满足需要一个完整环境才能运行的需求,例如自定义HQL和条件查询、会话相关问题等。我正在使用集成测试

我们已经有了相当多的单元测试(>500),在这些单元测试中,我们使用如下辅助函数来模拟默认情况下没有Grails模拟对应项的方法(如
withCriteria
withNewSession
,等等):

static mockCriteria(Class clazz, returnValue)
{
  def myCriteria = new Expando()
  myCriteria.list = {Closure cls -> returnValue}
  myCriteria.get = {Closure cls -> returnValue}
  clazz.metaClass.static.createCriteria = { -> myCriteria }
}
然后可以像这样测试代码:

mockCriteria(MyClass, [result])
assert myClass.createCriteria.list({ ... }) == [result]
到目前为止,我一直使用这种方法来满足我的需求

现在,我想添加一些集成测试,这些测试实际检查使用标准和HQL查询的方法的行为,以便于重构这些查询。我被这样一个事实所困扰,即
createCriteria
在我的测试中被替换,并且在单元测试阶段之后不会恢复它们的初始代码,从而阻止了我在集成阶段对它们进行测试

如何解决模拟条件(或HQL查询等)的问题,同时允许在集成测试中恢复原始行为


编辑:不幸的是,升级到Grails2不是一个选项。

我不是模仿标准,而是模仿使用标准的域方法

另外,Grails2.0承诺在单元测试中支持标准,而不是HQL。

试试以下方法:

void setUp() {
    super.setUp()
    registerMetaClass MyClass
}
幕后

def a = [1, 2, 3]
def oldMetaClass = ArrayList.metaClass
ArrayList.metaClass.find = { Closure cls -> 5 }
assert 5 == a.find{ it == 1}

ArrayList.metaClass = oldMetaClass  
assert 1 == a.find{ it == 1 }

还有,请看一看


(适用于1.3.7)

谢谢你,维克多。模拟使用自定义查询的方法是一个好主意。它假设每个查询都封装在一个小实例方法中(这是一个很好的实践,但并非所有地方都是这样。我建议进行重构)。无论如何,它会假设更新测试。我希望解决方案只涉及对
mockCriteria
的更改或重新初始化静态方法,但我不知道这是否可行。