Search code examples
testinggrailsspring-securitymocking

Mock Grails Spring Security Logged in User


Looking for a way to mock spring security in some unit/integration tests.

  • Grails: V2.1.0
  • Spring Security Core: V1.2.7.3

Controller has the following:

// some action
def index(){
   def user = getLoggedInUser()
   render ....
}
...

private getLoggedInUser(){
    return User.get(springSecurityService.principal.id)
}

I tried the following and various other ways but can't see to get it to work:

void testSomething(){
    def dc = new SomeController()
    dc.springSecurityService = [
            encodePassword: 'password',
            reauthenticate: { String u -> true},
            loggedIn: true,
            principal: [username:"Bob"]]
    dc.index() 
    ... assertion....

It seems that the user is not getting created and can't get the principal.id. Any suggestions or better alternatives?


Solution

  • I think the user is just being created, but not saved, and that's why it doesn't have an ID.

    The solution could be this:

    void testSomething(){
        def dc = new SomeController()
        def loggedInUser = new User(username: "Bob").save() // This way the user will have an ID
        dc.springSecurityService = [
            encodePassword: 'password',
            reauthenticate: { String u -> true},
            loggedIn: true,
            principal: loggedInUser]
        dc.index() ... assertion....
    

    There's an alternative:

    void testSomething(){
        def dc = new SomeController()
        def loggedInUser = new User(...).save()
        dc.metaClass.getLoggedInUser = { loggedInUser }
    ...
    

    I would suggest a refactor to getLoggedInUser:

    private getLoggedInUser(){
        return springSecurityService.currentUser
    }
    

    With this change, you could write:

    void testSomething(){
        def dc = new SomeController()
        def loggedInUser = new User(...).save()
        dc.springSecurityService = [
            encodePassword: 'password',
            reauthenticate: { String u -> true},
            loggedIn: true,
            getCurrenUser: { loggedInUser }]
    ...