I have a command object with constraints using spring beans in custom validator:
class UserPasswordCommand {
String currentPassword
//other fields....
static constraints = {
currentPassword validator: { currPass, upc ->
Holders.applicationContext.passwordEncoder.isPasswordValid(
Holders.applicationContext.springSecurityService.currentUser.password, currPass, null)
}
}
}
But when invoking new UserPasswordCommand(...) in unit test I get the following:
java.lang.NullPointerException: Cannot get property 'currentUser' on null object
So it appears that springSecurityService = null (as expected). I tried different actions to mock or "metaClass" it but unsuccessful.
Please advise if there is a better way to use beans from applicationContext in command objects or some approaches of mocking beans in Holders.applicationContext.
Thanks in advance!
UPDATE
Placed the following to setup()
section:
def setup() {
def appContext = Mock(ApplicationContext)
def springSecurityService = Mock(SpringSecurityService)
appContext.springSecurityService >> springSecurityService
Holders.metaClass.static.applicationContext = { appContext }
}
But no effect. springSecurityService is null in applicationContext retrieved from Holders. What am I doing wrong?
I resolved the issue by getting rid of Holders
in the original command object:
class UserPasswordCommand {
static passwordEncoder
static springSecurityService
String currentPassword
//...
static constraints = {
currentPassword validator: { currPass, upc ->
passwordEncoder.isPasswordValid(springSecurityService.currentUser.password, currPass, null)
}
//...
}
}
Added the mocks/stubs to test test:
def springSecurityService = Mock(SpringSecurityService)
def passwordEncoder = Mock(PasswordEncoder)
def setup() {
passwordEncoder.isPasswordValid(_, _, _) >> Boolean.TRUE
springSecurityService.currentUser >> Mock(User)
}
and:
given:
Map props = [
currentPassword: CURRENT_PASSWORD,
passwordEncoder: passwordEncoder,
springSecurityService: springSecurityService,
]
expect:
new UserPasswordCommand(props).validate()