【问题标题】:Grails Spring Security TestingGrails Spring 安全测试
【发布时间】:2012-09-30 04:35:56
【问题描述】:

我在我的项目中使用 Grails Spring Security 插件,现在想要对我的代码进行单元测试。我的控制器中有以下代码:

def index() {
    redirect action: 'show', params: [id: springSecurityService.currentUser.id]
}

我的测试类有以下代码:

void testIndex() {      
    controller.index()
    assert "/user/list" == response.redirectedUrl
}

此测试失败:

| Running 8 unit tests... 1 of 8
| Failure:  testIndex(xxx.UserControllerTests)
|  java.lang.NullPointerException: Cannot get property 'currentUser' on null object
    at xxx.UserController.index(UserController.groovy:12)
    at xxx.UserControllerTests.testIndex(UserControllerTests.groovy:19)

如何在测试用例中验证 Spring Security 用户?你会如何编写单元测试?

【问题讨论】:

    标签: unit-testing testing grails spring-security


    【解决方案1】:

    您对springSecurityService 的引用似乎为空。只要您的控制器中有一个名为springSecurityService 的字段,就应该注入它。您是否仅在索引方法中将其用作局部变量并且没有将其声明为字段?

    我的UserController如下:

    class UserController {
    
        /**
         * Dependency injection for the springSecurityService.
         */
        def springSecurityService
    
        ....
     }
    

    更新

    根据您对此答案的 cmets,您确实在控制器中声明了 springSecurityService 字段。我使用了我的工作应用程序并尝试了一个测试,该测试使用我的控制器方法反映了你的应用程序:

    @TestFor(UserController)
    class UserControllerTests {
    
        void testSomething() {
            controller.register()
        }
    }
    

    我也遇到了 NullPointerException。根据 Burt 的回答(我不知道这一点),我认为 springSecurityService 实例在单元测试执行的上下文中为空。

    【讨论】:

    • 在我的控制器中我有:class UserController { def springSecurityService ...
    • 我应该在 ControllerTest 中写下来吗?
    • @user1726376 不,您不应该在 ControllerTest 中使用它。我只是确保您有对 springSecurityService 的引用,因为您收到错误消息“无法在空对象上获取属性 'currentUser'”。
    【解决方案2】:

    对于这么简单的事情,我不会为复杂的模拟而烦恼,一个简单的

    controller.springSecurityService = [currentUser:[id:1]]
    

    就足够了。

    【讨论】:

    • 这不起作用。我得到org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object '{currentUser={id=1}}' with class 'java.util.LinkedHashMap' to class 'grails.plugin.springsecurity.SpringSecurityService' due to: groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: currentUser for class: grails.plugin.springsecurity.SpringSecurityService
    • @lmo 我建议的模拟只有在您的控制器中使用 def springSecurityService 时才有效,如果您有类型化声明 SpringSecurityService springSecurityService 则它将不起作用
    【解决方案3】:

    您必须使用功能测试来确保安全。单元测试使用模拟但没有可用的插件或真正的请求。 Spring Security 是使用过滤器链实现的,因此您需要一个真正运行的服务器。如果您使用模拟,您只是在测试模拟。

    【讨论】:

      猜你喜欢
      • 2011-10-22
      • 2012-08-01
      • 2020-07-01
      • 2014-02-15
      • 1970-01-01
      • 2020-06-28
      • 2014-02-05
      • 2012-09-09
      • 1970-01-01
      相关资源
      最近更新 更多