如何模拟从Controller测试类中的域类中注入的服务?

我有一个域类,它扩展了一个注入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)
    }
}

我想执行一个控制器测试。

@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.movi​​lrural.ExtraControllerTests)| java.lang.NullPointerException:无法在com.softamo.movi​​lrural.WithOwner.getCurrentUser(WithOwner.groovy:8)上的null对象上获取属性'currentUser'at com.softamo.movi​​lrural.WithOwner.isLoggedUserTheOwner(WithOwner.groovy:18)at com.softamo.movi​​lrural.ExtraControllerTests.testEdit(ExtraControllerTests.groovy:69)com.softamo.movi​​lrural.ExtraController.edit(ExtraController.groovy:39) 完成1个单元测试,1个失败853ms

我试图没有成功地嘲笑这样的安全服务:

Extra.metaClass.springSecurityService = new MockSpringSecurityService(user1)

甚至嘲笑该方法

Extra.metaClass.getCurrentUser = { return user1 }

任何想法我怎么能解决这个问题。


Grails 2.x支持使用'defineBeans'关闭来为测试环境定义spring bean。 它支持控制器中的依赖注入等,我不确定它是否也适用于域对象。 理论上,它应该跨域对象/控制器/服务保持一致

请参阅http://grails.org/doc/latest/guide/single.html#testing-'测试Spring Beans'部分。


这应该工作:

controller.springSecurityService = new SpringSecurityService()

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

controller.springSecurityService.metaClass.getCurrentUser = { -> return user1 }

我不确定你是否可以忽略->在上面的一行中,所以测试它。 如果你想在使用后或另一个测试用例之前清除这个模拟方法,可以使用下面的代码:

controller.springSecutiryService.metaClass = null

我发现了一个关于这个问题的好文章:将springSecurityService注入到Grails域类中以进行控制器单元测试

链接地址: http://www.djcxy.com/p/58991.html

上一篇: How to mock a service injected in a domain class from a Controller Test Class?

下一篇: Interpreting data from /proc/[id]/mountstats or /proc/self/mountstats