I have a user class like such:
class User {
transient springSecurityService
String displayName
String password
<snip>
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
}
And a UserController
.
I'm trying to write unit tests for the UserController
however I'm getting this error for save, update and delete tests:
java.lang.NullPointerException: Cannot invoke method encodePassword() on null object
What do I have to set up in the way of mocking to get this to work?
I have tried many combinations of mocking code such as the following, but I am at a loss.
defineBeans {
springSecurityService(SpringSecurityService)
}
Any advice would be greatly appreciated.
I personally don't like adding logic to production code to help satisfy a test. Sometimes you have to make a decision on what's best to do. Couple of options...
If this code (or code that runs into the same problem) is sprinkled throughout your application then you'd probably want to figure out a way to mock out these calls in your unit tests for all test cases so you're not duplicating your setup efforts everywhere. An easy way to mock this out is with metaClassing.
@Test
public void something() {
def user = ...
def springSecurityService = new Object()
springSecurityService.metaClass.encodePassword = {String password -> "ENCODED_PASSWORD"}
user.springSecurityService = springSecurityService
...
}
Now when the springSecurityService.encodePassword
gets invoked it should return "ENCODED_PASSWORD". I also create an Object
instead of instantiating a new SpringSecurityService
because if you instantiate an actual service then you may end up calling actual methods on that service unexpectedly and unknowingly and having your tests pass for the wrong reasons. I'd rather get a no such method error than a passing test that shouldn't be passing.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With