Unit testing a domain with transient property

拟墨画扇 提交于 2019-12-13 19:16:16

问题


I am trying to unit test a controller for User domain generated by Spring Security Core Plugin. The controller was generated with grails generate-all. The domain has a transient property called springSecurityService. In my unit test I am trying to mock that service and assign this transient variable to my mocked version. However, I get this error :

No such property: springSecurityService for class: com.myapp.security.SecUser Possible solutions:
springSecurityService groovy.lang.MissingPropertyException: No such property: springSecurityService for class: 
com.myapp.security.SecUser at com.myapp.security.SecUserControllerTests.setUp(SecUserControllerTests.groovy:26)

Here is my domain look like:

class SecUser {
    transient springSecurityService
    String username
    String password
    boolean enabled
    boolean accountExpired
    ....
    def beforeInsert() {
        encodePassword()
    }
    protected void encodePassword() {
        password = springSecurityService.encodePassword(password)
    }
}

Here is how my test look like:

 package com.myapp.security

 import org.junit.*
 import grails.test.mixin.*
 import com.myapp.system.*
 import grails.plugins.springsecurity.*

 @TestFor(SecUserController)
 @Mock([SecUser,SpringSecurityService])
 class SecUserControllerTests {

    @Before void setUp() { 
       def service = mockFor(SpringSecurityService)
       service.demand.encodePassword(1..2) { a -> return 'd3jk3j4ls234'}
       def control = service.createMock()
       SecUser.springSecurityService = control
   }

Not sure what I am doing wrong or even I can even do something like this with transient property?


回答1:


Could be a mockup situation, See if this works:

@Before void setUp() { 
    def service = mockFor(SpringSecurityService)
    // using the groovy MetaClass runtime
    service.metaclass.encodePassword = {def a -> 'd3jk3j4ls234'}
    SecUser.springSecurityService = service
}

or a more static solution:

@Before void setUp() { 
    secUser.springSecurityService = [
        encodePassword : {def a -> 'd3jk3j4ls234'}
    ] as SpringSecurityService
}



回答2:


You're trying to assign your mocked springSecurityService to the SecUser class (as if it were a static), which won't work when it's an instance variable. I'm not an expert on the new Grails 2 testing annotations but I believe that if you replace

SecUser.springSecurityService = control

with

SecUser.metaClass.getSpringSecurityService = {-> control}

then it should do what you want.



来源:https://stackoverflow.com/questions/12272041/unit-testing-a-domain-with-transient-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!