Mock Grails Spring Security登录用户

Dan*_*ift 5 testing grails mocking spring-security

寻找在某些单元/集成测试中模拟弹簧安全性的方法.

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

控制器具有以下内容:

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

private getLoggedInUser(){
    return User.get(springSecurityService.principal.id)
}
Run Code Online (Sandbox Code Playgroud)

我尝试了以下和其他各种方法,但无法让它工作:

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

似乎用户没有被创建并且无法获得principle.id.任何建议或更好的选择?

Tom*_*ero 5

我认为用户只是在创建,而没有保存,这就是为什么它没有ID的原因。

解决方案可能是这样的:

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....
Run Code Online (Sandbox Code Playgroud)

还有一种选择:

void testSomething(){
    def dc = new SomeController()
    def loggedInUser = new User(...).save()
    dc.metaClass.getLoggedInUser = { loggedInUser }
...
Run Code Online (Sandbox Code Playgroud)

我建议重构为getLoggedInUser:

private getLoggedInUser(){
    return springSecurityService.currentUser
}
Run Code Online (Sandbox Code Playgroud)

通过此更改,您可以编写:

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