Mock Grails Spring Security user logged in

Look for a way to mock spring safety in some unit / integration tests.

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

The 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 other ways, but can't see how this works:

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 created and cannot receive the file principal.id. Any suggestions or better alternatives?

+5
source share
1 answer

I think that the user is only created, but not saved, and why he does not have an identifier.

The solution may be as follows:

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 is an alternative:

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

I would suggest the getLoggedInUser refactor:

private getLoggedInUser(){
    return springSecurityService.currentUser
}

With this change you can write:

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

All Articles