我试图为grails控制器编写单元测试用例,其结构如下:
class MyController{
def save(){
def myDomain = new MyDomain(params)
business validation 1
business validation 2
myDomain.writedatasource.save()
business validation 3
business validation 4
}
}由于单元测试没有加载Datasource.groovy,所以在单元测试期间写数据源不可用,所以“业务验证3”和“业务验证4”的测试用例就会失败
groovy.lang.MissingPropertyException:没有这样的属性:类的写数据源: MyDomain
如何修改测试用例以测试验证场景3和4?
测试用例很简单,如下所示:
void testSave(){
...setup...
controller.save()
assert conditions
....
}发布于 2014-01-17 17:04:57
不确定这是否能成功,但您可以尝试:
def 'the controller call the save method in writedatasource'() {
given:
def calls = 0
and:
def myDomainInstance = new MyDomain()
and:
MyDomain.metaClass.getWritedatasource = { new Object() }
and:
Object.metaClass.save = { Map attrs ->
calls++
}
when:
controller.save()
then:
calls == 1
}但是您所做的唯一的事情就是测试在写数据源下调用保存,所以最好也有一个集成测试。如果是这样的话,请在http://grails.1312388.n4.nabble.com/Mocking-in-a-unit-test-a-domain-object-multiple-datasources-td4646054.html回答,因为他们似乎也有同样的问题。
发布于 2015-02-11 23:47:15
解决原始问题:
我遇到了这种情况,并且不得不嘲笑许多更多的方法,而不仅仅是在多个域上“保存”。因此,我重写了域的getter,只返回调用域实例:
def setup() {
[MyDomain1, MyDomain2].each { Class clazz ->
mockDomain(clazz)
clazz.metaClass.getWritedatasource = {
return delegate
}
clazz.metaClass.'static'.getWritedatasource = {
return delegate
}
}
}这也避免了包含@DirtiesRuntime,因为我没有更新我想要清理的任何东西的metaClass。
最重要的是,无论调用数据源(无论是域类还是实例),都应该使用来自mockDomain的GORM幻想来修饰,这意味着我不必模拟任何GORM方法。
如果你想要动态数据源怎么办?
在我的特定情况下,数据源是可配置的,并且可能会根据环境而改变。如果您在类似的情况下,可以在域映射中配置它:
static mapping = {
datasources Holders.grailsApplication?.config.dynamic?.datasources
...
}其中dynamic.datasources是一个数据源名称数组。然后,在测试设置中:
def setup() {
grailsApplication.config.dynamic.datasources = ['foo', 'bar']
[MyDomain1, MyDomain2].each { Class clazz ->
mockDomain(clazz)
grailsApplication.config.dynamic.datasources.each{
clazz.metaClass."get${it.capitalize()}" = {
return delegate
}
clazz.metaClass.'static'."get${it.capitalize()}" = {
return delegate
}
}
}
}https://stackoverflow.com/questions/21171658
复制相似问题