0

我正在使用Grails Spring Security CoreGrails Spring Security REST 插件,我才刚刚开始设置。User我用一个类和一个类(默认值)初始化插件,然后按照我在 Grails 网站上找到Authority的指南编写集成测试。

它说将以下内容放入集成测试中:

def "test a user with the role ROLE_BOSS is able to access /api/announcements url"() {
    when: 'login with the sherlock'
    RestBuilder rest = new RestBuilder()
    def resp = rest.post("http://localhost:${serverPort}/api/login") { 
        accept('application/json')
        contentType('application/json')
        json {
            username = 'sherlock'
            password = 'elementary'
        }
    }

    then:
    resp.status == 200
    resp.json.roles.find { it == 'ROLE_BOSS' }
}

我继续做了类似的事情,它与 bootstrapped 一起工作User,但是当我尝试使用在测试方法本身中创建的进行完全相同的测试时User,它会因401HTTP 响应代码而失败。

我试图运行的代码:

void "check get access token"() {
    given:
    RestBuilder rest = new RestBuilder()
    new User(username: "securitySpecTestUserName", password: "securitySpecTestPassword").save(flush: true)
    assert User.count == 2

    when:
    def resp = rest.post("http://localhost:${serverPort}/api/login") {
        accept('application/json')
        contentType('application/json')
        json {
            username = "securitySpecTestUserName"
            password = "securitySpecTestPassword"
        }
    }

    then:
    resp.status == 200
}

请注意,User.count == 2断言通过是因为测试方法中有一个UserinBootstrap.groovy和一个 create。

为什么这可以工作并通过引导程序User完全没有任何问题,但不是在方法中创建的问题?有没有办法可以编写此集成测试,以便我可以以这种方式测试插件中/api/login包含的端点?grails-spring-security-rest

4

1 回答 1

0

您在给定部分中创建的用户处于尚未提交的事务中。当您进行 REST 调用时,api/login 控制器将在一个看不到您未提交用户的新事务中运行。

几个选项(还有其他选项)...

  1. 在 BootStrap.groovy 中创建用户

    def init = { servletContext ->
      environments {
        test {
          new User(username: "securitySpecTestUserName", password: "securitySpecTestPassword").save(flush: true)
        }
      }
    }
    
  2. 进行 REST 调用以创建用户 - 假设您具有此类功能

  3. 在设置中创建用户

    @Integration
    @Rollback
    class UserIntSpec extends Specification {
    
      def setup() {
        new User(username: "securitySpecTestUserName", password: "securitySpecTestPassword").save(flush: true)
      }
    
      void "check get access token"() {
        given:
        RestBuilder rest = new RestBuilder()
    
        when:
        def response = rest.post("http://localhost:${serverPort}/api/login") {
          accept('application/json')
          contentType('application/json')
          json {
            username = "securitySpecTestUserName"
            password = "securitySpecTestPassword"
          }
        }
    
       then:
       response.status == HttpServletResponse.SC_OK
    
       when:
       def token = response.json.access_token
    
       then:
       token
      }
    }
    

注意:在 Grails >= 3.0 中,setup()在单独的事务中运行并持久化(为什么它可以解决您的问题),不会回滚。任何数据都需要手动清理。

我建议您阅读有关测试的 grails 文档:集成测试

于 2017-07-30T01:32:05.613 回答