我确信这是一个相当普遍的情况。我正在使用Spring Security Core插件,并且想要创建一个具有限于某些角色的Person的域模型:
class Workgroup {
Person manager
...
static constraints = {
manager(validator: {mgr ->
// it feels like there should be a more elegant, groovy way of doing this.
def auths = mgr.getAuthorities();
def returny = false
auths.each {
if(it.authority == 'ROLE_MANAGER')
{
returny = true
}
}
return returny
})
}
}
此测试失败了,就像一个mofo:
void testInvalidManager() {
def nick = new Person(username:'Nick')
def nonManagerRole = new Role(authority:'ROLE_EMPLOYEE')
UserRole.create(nick,nonManagerRole)
def awesome = new Workgroup(name:'mooCows', manager:nick)
mockForConstraintsTests(Workgroup, [awesome])
assertFalse awesome.validate()
assertEquals "validator", awesome.errors["manager"]
}
testInvalidManager错误没有方法签名:users.UserRole.save()适用于参数类型:(java.util.LinkedHashMap)值:[[flush:false,insert:true]]可能的解决方案:wait(), any(),wait(long),use([Ljava.lang.Object;),isCase(java.lang.Object),each(groovy.lang.Closure)
groovy.lang.MissingMethodException:没有方法签名:users.UserRole.save()适用于参数类型:(java.util.LinkedHashMap)值:[[flush:false,insert:true]] 可能的解决方案:wait(),any(),wait(long),use([Ljava.lang.Object;),isCase(java.lang.Object),each(groovy.lang.Closure) at users.UserRole.create(UserRole.groovy:32) at users.UserRole.create(UserRole.groovy) at users.UserRole $ create.call(Unknown Source) at users.WorkgroupTests.testInvalidManager(WorkgroupTests.groovy:17)
整合比单元测试更好吗?我是否需要模拟UserRole(如果是,如何?)?这些类型的测试通常如何进行?
答案 0 :(得分:2)
UserRole.create()
来电save()
,因此您需要使用mockDomain()
而非mockForConstraintsTests()
。
但是,只有当你使用模拟测试域模型时才会这样,我永远不会这样做。在测试使用域类的控制器或其他类时,应该使用Grails中的模拟支持,但不应该使用真正的持久性,创建数据库(甚至是内存中)等等。通过删除该依赖关系,您将专注于当前层,相信其他层已经过适当测试。但是当你使用mocking来测试域类时,你真的只是在测试模拟框架。所以我总是对域类使用集成测试,因此它们针对真实数据库运行。
要回答代码示例中的隐含问题,我将约束写为
static constraints = {
manager validator: { mgr ->
mgr.authorities.find { it.authority == 'ROLE_MANAGER' } != null
}
}
它的批量问题是,当一个常规for循环更可取时,你正在使用each(),因为你可以从for循环返回。仅当您真的想要在每个实例上调用闭包时才使用each()。这是一个比另一个更不时髦但使用for循环的那个:
static constraints = {
manager validator: { mgr ->
for (auth in mgr.getAuthorities()) {
if (it.authority == 'ROLE_MANAGER') {
return true
}
}
return false
}
}