如何从Controller Test Class模拟注入域类的服务?

Ser*_*Amo 7 grails unit-testing mocking spring-security

我有一个域类,它扩展了一个抽象类,它注入了spring安全核心插件服务.

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

我想实现一个控制器测试.

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

如果我运行上述测试,我得到:

test-app ExtraController.testEdit --unit --echoOut | 运行1单元测试... 1 of 1 - 从testEdit-- |输出 失败:testEdit(com.softamo.movi​​lrural.ExtraControllerTests)| java.lang.NullPointerException:无法在com.softamo.movi​​lrural.WithOwner.getCurrentUser(WithOwner.groovy:8)的com.softamo.movi​​lrural.WithOwner.isLoggedUserTheOwner(WithOwner.groovy:18)at null对象上获取属性'currentUser' Com.softamo.movi​​lrural.ExtraController.edit(ExtraController.groovy:39)at com.softamo.movi​​lrural.ExtraControllerTests.testEdit(ExtraControllerTests.groovy:69)| 完成1个单元测试,1个在853ms失败

我试过像这样嘲笑安全服务没有成功:

Extra.metaClass.springSecurityService = new MockSpringSecurityService(user1)
Run Code Online (Sandbox Code Playgroud)

甚至嘲笑方法

Extra.metaClass.getCurrentUser = { return user1 }
Run Code Online (Sandbox Code Playgroud)

知道我怎么能解决这个问题.

Tom*_*ski 1

这应该有效:

controller.springSecurityService = new SpringSecurityService()
Run Code Online (Sandbox Code Playgroud)

如果你想在这个服务中模拟 getCurrentUser 方法:

controller.springSecurityService.metaClass.getCurrentUser = { -> return user1 }
Run Code Online (Sandbox Code Playgroud)

我不确定你是否可以->在上面一行中省略,所以测试一下。如果您想在使用后或在另一个测试用例之前清除此模拟方法,请使用以下命令:

controller.springSecutiryService.metaClass = null
Run Code Online (Sandbox Code Playgroud)