【问题标题】:get current user in grails spock unit testing which uses spring security在使用spring security的grails spock单元测试中获取当前用户
【发布时间】:2014-08-08 06:34:38
【问题描述】:
package com.rohan

import grails.test.mixin.*
import spock.lang.Specification
import grails.plugins.springsecurity.SpringSecurityService
import grails.test.mixin.domain.DomainClassUnitTestMixin
import com.rohan.meta.MetaServiceCategory

@TestFor(ProjectDashBoardController)
            @Mock([SpringSecurityService,User,Project,MetaServiceCategory,ProjectIntroduction,ProjectDetails,ProjectAdditionalInfo,SPCompany,BuyerCompany,Conversation,ServiceCategory,UserAuthService,TimeSheetService,ProjectService])
class ProjectDashBoardControllerSpec extends Specification {

    void "test timeSheets action"() {

        given:
        BuyerCompany buyerCompany = new BuyerCompany()
        Project testProject = new Project(title: "test    Project",projectId:"0411",buyerCompany:buyerCompany)
        testProject.save()
        println "project : "+testProject

        when:"When Project Id Given"
        controller.params.id = "00411"
        controller.timeSheets()

        then:
        response.redirectUrl.endsWith '/dashboard/index'
    }
}

这是控制器代码:

class ProjectDashBoardController {

    def springSecurityService
    def userAuthService

    def timeSheets(){
        def project=Project.findByProjectId(params.id)
        if(project){
            def user = userAuthService.getCurrentUser()
            // Do Something
        } else {
            redirect(controller:'dashboard',action:'index')
        }
     }
}

@OPAL 我想这就是你要问的

类 UserAuthService {

def getCurrentUser(){ def 用户 = springSecurityService.currentUser 返回用户 } } 最后我收到以下错误:

Cannot get property 'currentUser' on null object
    at com.rohan.UserAuthService.getCurrentUser(UserAuthService.groovy:22)
    at com.rohan.ProjectDashBoardController.timeSheets(ProjectDashBoardController.groovy:130)
    at com.rohan.ProjectDashBoardControllerSpec.test timeSheets action(ProjectDashBoardControllerSpec.groovy:29) 

【问题讨论】:

    标签: spring-security grails-plugin spock


    【解决方案1】:

    我没有看到经过验证的答案,也许它会帮助其他人:

    使用 grails,如果您需要 userAuthService 或其他服务(如 grails 核心服务或您自己的服务),您有多种可能性,例如:

    1. 在单元测试中存根/模拟它们并定义行为
    2. 让您的单元测试成为集成测试

    1.在单元测试中存根/模拟它们

    这里有一个存根:

    void "test timeSheets action"() {
        given:
        ...your code...
        def userAuthService = Stub(UserAuthService)
        User currUser = new User(email: "current@current.fr", firstname: "firstname")
        // Here we define the behaviour of our Stubbed service :
        userAuthService.getCurrentUser() >> currUser
    
        and:"we inject our fake userAuthService"
        controller.userAuthService = userAuthService
    
        when:"When Project Id Given"
        ...your code...
    
        then:
        ...your code...
    }
    

    注意:您可以使用 Mock(UserAuthService) 代替 Stub(UserAuthService)。然后,您将能够在“then”部分验证 getCurrentUser() 是否已被调用过一次

    1 * userAuthService.getCurrentUser()
    

    2。让您的单元测试成为集成测试

    来自关于测试的 grails 文档

    集成测试与单元测试的不同之处在于您拥有完全访问权限 到测试中的 Grails 环境。 Grails 使用内存中的 H2 用于集成测试的数据库并清除所有数据 测试之间的数据库。

    【讨论】:

      【解决方案2】:

      你声明了userAuthService,但我看不到它被注入或初始化的任何地方。

      【讨论】:

      • injected..??..你能解释一下我是怎么做到的...这会很有帮助
      • 不知道怎么做。我不是 Grails 开发人员。只要看看它会导致问题。
      【解决方案3】:

      如果这是一个单元测试(不是集成测试),您应该只创建 userAuthServiceMockStub 并将其注入控制器。通过在这种特定情况下注入,只需使用像 controller.userAuthService = serviceStub 这样的设置器。

      【讨论】:

        【解决方案4】:
        void "test timeSheets action"() {
            setup:
            testUser = new User()
            controller.userAuthService = [currentUser: testUser]
        
        
            given:
            BuyerCompany buyerCompany = new BuyerCompany()
            Project testProject = new Project(title: "test    Project",projectId:"0411",buyerCompany:buyerCompany)
            testProject.save()
            println "project : "+testProject
        
            when:"When Project Id Given"
            controller.params.id = "00411"
            controller.timeSheets()
        
            then:
            response.redirectUrl.endsWith '/dashboard/index'
        }
        

        作为测试设置部分的一部分,模拟测试用户并注入到 userAuthServices。我遇到了类似的问题,它解决了。

        【讨论】:

          猜你喜欢
          • 2014-06-10
          • 1970-01-01
          • 1970-01-01
          • 2018-12-27
          • 2018-02-13
          • 1970-01-01
          • 2017-01-06
          • 2014-06-21
          • 2016-06-17
          相关资源
          最近更新 更多