我有一个域类,它扩展了一个注入spring security core plugin服务的抽象类。
class Extra extends WithOwner {
String name
}
abstract class WithOwner {
transient springSecurityService
User user
def getCurrentUser() {
return springSecurityService.currentUser
}
def beforeValidate() {
if(!user) {
user = getCurrentUser()
}
}
Boolean isLoggedUserTheOwner(){
return (user?.id == getCurrentUser()?.id)
}
}
我想实施控制器测试。
@TestFor(ExtraController)
@Mock([Extra, User, UserRole, Role])
class ExtraControllerTests {
void testEdit() {
def utils = new TestUtils()
def user1 = utils.saveUser1()
populateValidParams(params)
def extra = new Extra(params)
extra.user = user1
assert extra.save() != null
params.id = extra.id
def model = controller.edit() // Line 69
assert model.extraInstance == extra
}
}
如果我运行上述测试,我会得到:
test-app ExtraController.testEdit --unit --echoOut |运行1单元测试... 1 of 1 - 来自testEdit的输出 - |失败:testEdit(com.softamo.movilrural.ExtraControllerTests) | java.lang.NullPointerException:无法在null对象上获取属性“currentUser” at com.softamo.movilrural.WithOwner.getCurrentUser(WithOwner.groovy:8) at com.softamo.movilrural.WithOwner.isLoggedUserTheOwner(WithOwner.groovy:18) at com.softamo.movilrural.ExtraController.edit(ExtraController.groovy:39) at com.softamo.movilrural.ExtraControllerTests.testEdit(ExtraControllerTests.groovy:69) |完成1个单元测试,1个在853ms失败
我试图像这样嘲笑安全服务但没有成功:
Extra.metaClass.springSecurityService = new MockSpringSecurityService(user1)
甚至嘲笑方法
Extra.metaClass.getCurrentUser = { return user1 }
我知道如何解决这个问题。
答案 0 :(得分:2)
Grails 2.x支持使用'defineBeans'闭包为测试环境定义spring bean。 它支持控制器中的依赖注入等,我不确定它是否也适用于域对象。从理论上讲,它应该跨域对象/控制器/服务一致
请参阅http://grails.org/doc/latest/guide/single.html#testing - “测试春豆”部分。
答案 1 :(得分:1)
这应该有效:
controller.springSecurityService = new SpringSecurityService()
如果你想在这个服务中模拟getCurrentUser方法:
controller.springSecurityService.metaClass.getCurrentUser = { -> return user1 }
我不确定你是否可以在上面的一行中省略->
,所以要测试一下。如果要在使用之后或在另一个测试用例之前清除此模拟方法,请使用:
controller.springSecutiryService.metaClass = null
答案 2 :(得分:1)