我正在Grails 2.1.1下编写一些基于Spock规范的单元测试。我无法将springSecurityService
注入我单位使用的域对象中。
这是我到目前为止所拥有的,
@Mock([SecUser])
@TestFor(FooService)
class FooServiceSpec extends Specification {
def "test some stuff"() {
given:
def mockSecUserService = Mock(SecUserService)
mockSecUserService.emailValid(_) >> { true }
mockSecUserService.checkUsername(_) >> { null }
service.secUserService = mockSecUserService
def mockSpringSecurityService = Mock(SpringSecurityService)
mockSpringSecurityService.encodePassword(_) >> { 'tester' }
// FIXME this needs to be injected somehow
def params = [
email: 'unittest@test.com',
username: 'unittester',
password: 'tester',
password2: 'tester'
]
when:
def result = service.createUser(params)
then:
// test results
}
}
所以会发生的事情是我的测试服务会抛出NullPointerException
,因为不会注入mockSpringSecruityService。我的服务中的createUser调用验证了一些参数,然后创建了一个SecUser
域对象。
SecUser
注入了以下服务以支持密码编码,
class SecUser {
transient springSecurityService
我无法弄清楚的是以域名类可用的方式注入此服务。我知道有一些帖子已经与此主题相关但其中大多数都假设测试可以实例化域对象,但在我的情况下,实例化是正在测试的单元的一部分。
我尝试了以下代替FIXME,
defineBeans {
mockSpringSecurityService(SpringSecurityService) { bean ->
bean.autowire = true
}
}
但结果我得到了跟随错误,
| groovy.lang.MissingMethodException:没有方法签名: grails.plugins.springsecurity.SpringSecurityService.call()是 适用于参数类型:(java.lang.Class, skillz.GameAccountServiceSpec $ _spock_feature_0_0_closure4_closure5) 值:[class grails.plugins.springsecurity.SpringSecurityService, ...]可能的解决方案:wait(),any(),find(),dump(),collect(), 的grep()
有什么想法吗?
答案 0 :(得分:6)
我最终做的工作是,
SecUser.metaClass.encodePassword = { null }
在我的域对象encodePassword
中是使用springSecurityService
bean的方法。因此,如果我理解正确,这只是覆盖此方法什么都不做(方法是无效的)。
我更喜欢使用metaClass来虚拟注入bean,但我尝试
SecUser.metaClass.getSpringSecurityService = { mockSpringSecurityService }
当encodePassword尝试使用SpringSecurityService时,会使用NPE。
我觉得这是一个不太理想的工作,所以我喜欢有人给出一个不那么讨厌的答案。