问题
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