扩展Grails模拟单元测试(createCriteria,withNewSession等...)

时间:2011-11-29 14:13:18

标签: unit-testing grails groovy

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

我们已经有相当多的单元测试(> 500),我们习惯于模拟默认情况下没有Grails模拟对应方法的方法(如withCriteriawithNewSession,等)使用这样的辅助函数:

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查询等)的问题,同时允许在集成测试中恢复原始行为?

编辑:不幸的是,升级到Grails 2不是一种选择。

2 个答案:

答案 0 :(得分:1)

我宁愿嘲笑不是标准,而是使用它们的域方法。

另外,Grails 2.0承诺在单元测试中提供标准支持 - 而不是HQL。

答案 1 :(得分:1)

试试这个:

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 }

对于mockCriteria来看看

https://github.com/fabiooshiro/plastic-criteria

(适用于1.3.7)