get current user in grails spock unit testing which uses spring security

旧城冷巷雨未停 提交于 2019-12-24 05:57:50

问题


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'
    }
}

Here is controller code:

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 i think that's what u asking

class UserAuthService {

def getCurrentUser(){ def user = springSecurityService.currentUser return user } } And finally I receive the following error:

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) 

回答1:


I don't see validated answer, maybe it will help somebody else :

With grails, if you want userAuthService or other services (like grails core services or your own) you have several possibilities like :

  1. Stub/Mock them in a unit test and define the behaviour
  2. Make your unit test an integration test

1. Stub/Mock them in a unit test

Here with a Stub :

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...
}

NOTE : you can use Mock(UserAuthService) in place of Stub(UserAuthService). Then you'll be able to verify in the "then" part that getCurrentUser() has been called once with

1 * userAuthService.getCurrentUser()

2. Make your unit test an integration test

From grails documentation about Testing

Integration tests differ from unit tests in that you have full access to the Grails environment within the test. Grails uses an in-memory H2 database for integration tests and clears out all the data from the database between tests.




回答2:


You declare userAuthService but I can't see any place it's injected or initialized.




回答3:


If that's a unit test (not integration one) you should just create Mock or Stub of your userAuthService and inject it into the controller. By inject in this specific case just use setter like 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'
}

As part of setup section of your test, Mock Test User and inject to userAuthServices. I had similar problem and it did the fix.



来源:https://stackoverflow.com/questions/24277504/get-current-user-in-grails-spock-unit-testing-which-uses-spring-security

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!