Grails Spring 安全测试
Posted
技术标签:
【中文标题】Grails Spring 安全测试【英文标题】:Grails Spring Security Testing 【发布时间】: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 用户?你会如何编写单元测试?
【问题讨论】:
【参考方案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 是使用过滤器链实现的,因此您需要一个真正运行的服务器。如果您使用模拟,您只是在测试模拟。
【讨论】:
以上是关于Grails Spring 安全测试的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 grails 在单元测试中模拟 springSecurityService
Grails,从 Acegi 升级到 Spring 安全插件