2012-04-23 76 views
7

我有一个域类,它扩展了一个抽象类,它注入了spring security core plugin服务。如何模拟从Controller测试类中注入到域类中的服务?

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 
    } 
} 

如果我运行上面的测试中,我得到:

测试应用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)上的空对象 上无法获取属性'currentUser'。com.softamo.movi​​lrural.WithOwner.isLoggedUserTheOwner(WithOwner.groovy:18)上的 ) at 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) 

甚至嘲讽的方法

Extra.metaClass.getCurrentUser = { return user1 } 

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

+0

您好!我陷入了同样的问题。你有没有为你的问题找出解决方案?或者,也许你有一个侧面注入一个域对象内的服务没有单元测试自动装配? – snowindy 2012-11-18 19:47:53

+0

这个问题有什么好运?,面临同样的问题。 – 2015-11-01 06:27:29

回答

1

这应该工作:

controller.springSecurityService = new SpringSecurityService() 

如果你想嘲笑这个服务getCurrentUser方法:

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

我不知道,如果你能在上面一行ommit ->,因此测试它。如果你想使用接连测试用例或之前清除这个模拟的方法使用:

controller.springSecutiryService.metaClass = null 
+1

这解释了如何将服务注入控制器,他的问题是如何模拟域对象中的服务。 – 2012-04-23 09:26:00

+0

只是为了记录,你可以省略' - >'并简化为'getCurrentUser = {user1}' – 2013-08-08 16:13:33

2

Grails的2.x支持定义使用“defineBeans”封闭测试环境的Spring bean。 它支持在控制器等依赖注入,我不知道它是否也适用于域对象。理论上,它应该在域对象/控制器/服务中保持一致

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

+0

我试过这个但是不起作用。不知道如何为域类设置它。defineBeans {0} {0} springSecurityService(new MockSpringSecurityService(user1)) – 2012-04-23 11:22:47

+0

当您定义Spring bean时,您不需要执行新的MockSpringSecurityService(),只需springSecurityService(MockSpringSecurityService) – 2012-04-23 13:23:34

相关问题