2012-10-09 130 views
5

我为我的项目使用了Grails Spring Security Plugin,现在想单元测试我的代码。我有下面的代码在我的控制器:Grails Spring Security Testing

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) 

我如何可以验证弹簧安全用户在一个测试案例中?你会如何编写单元测试?

回答

0

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

UserController如下:

class UserController { 

    /** 
    * Dependency injection for the springSecurityService. 
    */ 
    def springSecurityService 

    .... 
} 

UPDATE

根据您的意见对这个答案,你是在你的控制器声明springSecurityService场。我把我的工作的应用程序,并试图,反映你与我的控制器方法测试:

@TestFor(UserController) 
class UserControllerTests { 

    void testSomething() { 
     controller.register() 
    } 
} 

我得到一个NullPointerException为好。从Burt的回答(我不知道这一点),我认为springSecurityService实例在单元测试执行的上下文中为null。

+0

在我的控制,我有: 类UserController的{ \t \t高清springSecurityService ... – Nadya

+0

我应该写下来的ControllerTest? – Nadya

+0

@ user1726376不,你不应该在ControllerTest中需要它。我只是确保你有一个'springSecurityService'的引用,因为你有错误消息“无法获得属性'currentUser'在空对象上”。 –

3

对于一些这个简单,我不会用复杂的嘲笑打扰,一个简单的

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

就足够了。

+0

这不起作用。我得到'org.codehaus.groovy.runtime.typehandling.GroovyCastException:无法将类'java.util.LinkedHashMap'的对象'{currentUser = {id = 1}}'转换为class'grails.plugin.springsecurity.SpringSecurityService' to:groovy.lang.ReadOnlyPropertyException:无法设置只读属性:currentUser类:grails.plugin.springsecurity.SpringSecurityService' – lmo

+0

@lmo我建议的模拟只有在你的控制器中使用'def springSecurityService'时才会起作用,如果你有一个类型化的声明'SpringSecurityService springSecurityService',你就不会工作 –

7

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