我正在尝试按照文档对Grails服务的单元测试中的Domain类进行一些简单的模拟,但它似乎根本不起作用,因为实例的查询总是返回null。我错过了一些简单的事吗?这是我的代码的相关部分,为了清楚起见,我更改了类和测试方法名称:
@TestFor(MyService)
@TestMixin(DomainClassUnitTestMixin)
class MyServiceTests {
void testMyThing() {
defineBeans {anotherService(AnotherService)} //My service under test uses another service, unlikely relevant?
MyUser.metaClass.isDirty = { //workaround for mockDomain not adding isDirty method.
println("dirty check called");
}
mockDomain(MyUser, [
[username: "email@gmail.com", accountType: UserType.STANDARD, id: 1L],
[username: "user@gmail.com", accountType: UserType.STANDARD, id:3L],
[username: "bizuser@domain.com", accountType: UserType.BUSINESS, id:2L]
])
MyUser user1 = MyUser.get(1);
System.out.println("user 1: ${user1}"); // output is 'user 1: null'
MyUser user1byName = MyUser.findByUsername("email@gmail.com");
System.out.println("user 1 by name: ${user1byName}"); // output is 'user 1 by name: null'
... the actual testing stuff which would love to have non null MyUser objects ...
}
}
答案 0 :(得分:11)
我想出来了,你会想到我会想到这个,因为我以前被它咬过了。问题在于验证,如果Domain类有验证错误,Grails的默认GORM行为默默地无法在save()上保存数据(当您为模拟实例传递数据时,mockDomain必须使用该数据)。 MyUser需要一个非空密码。
很久以前我在我的Config.groovy中为我的应用程序添加了grails.gorm.failOnError=true
,所以我再也没有想过它,但当然不会读取单元测试
在我看来,这使得mockDomain的签名非常脆弱(我找不到设置failOnError = true的方法)。我将模拟数据设置切换到以下结果,结果完全相同,但如果您错误地设置了数据,会立即失败。
@Mock(MyUser)
class MyServiceTests {
...
void testMyThing() {
new MyUser(username: "email@gmail.com",
accountType: UserType.STANDARD,
id: 1L).save(failOnError:true) //throws exception because MyUser requires password field to be non blank
...
}
}