将模拟服务注入到Grails单元测试的域类中?

Jam*_*hon 7 testing grails groovy unit-testing spock

我正在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
    }
}
Run Code Online (Sandbox Code Playgroud)

所以会发生的事情是我的测试服务会抛出一个NullPointerException因为没有注入mockSpringSecruityService.我的服务中的createUser调用验证一些参数,然后创建一个SecUser域对象.

SecUser注入进去,支持密码加密下列服务,

class SecUser {
    transient springSecurityService
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚的是以域类可用的方式注入此服务.我知道有一些帖子已经与这个主题相关,但是大多数帖子都认为测试可以实例化域对象,但在我的情况下,实例化是被测单元的一部分.

我试过以下代替FIXME,

defineBeans {
    mockSpringSecurityService(SpringSecurityService) { bean -> 
        bean.autowire = true
    }
}
Run Code Online (Sandbox Code Playgroud)

但结果我得到了跟随错误,

| 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()

有任何想法吗?

Jam*_*hon 6

我最终做的工作是,

SecUser.metaClass.encodePassword = { null }
Run Code Online (Sandbox Code Playgroud)

在我的域对象中encodePassword是使用springSecurityServicebean 的方法.因此,如果我理解正确,这只是覆盖此方法什么也不做(方法是无效的).

我更喜欢使用metaClass来虚拟注入bean,但是我尝试了

SecUser.metaClass.getSpringSecurityService = { mockSpringSecurityService }
Run Code Online (Sandbox Code Playgroud)

当encodePassword尝试使用SpringSecurityService时,会使用NPE.

我觉得这是一个不太理想的工作,所以我喜欢有人给出一个不那么讨厌的答案.