控制器(用于休息api)的Grails集成测试不起作用

时间:2015-01-21 23:02:26

标签: rest grails integration-testing

Grails 2.4.4。 我们有很多JSON / REST API端点,如下所示,但代码更多(注意:我们不能使用RestfulController,因为我们有SpringSecurity而且它们不兼容)

e.g。

class SessionController 
def sessionService
static namespace = 'v1'
static allowedMethods = [loginPlayer: "POST"]

def loginPlayer()  {
    def payload = request.JSON

    try {
        // Check params are there.
        if (payload.user == null) {
            render(status: 422, contentType: 'application/json') {
                 [
                  'result'     : -1
                  'description': "missing params"
                 ]
            return
        }

        def result = sessionService.loginPlayer(
                    payload.user,
                    payload.password
            )

        if (result.returnCode == 0) {
                render(status: 200, contentType: 'application/json') {
                    [
                      'result' : 0
                      'authToken' : result.authToken
       etc.

我们目前正在使用SOAPUI手动测试它们。我们迫切希望自动化集成测试能够针对数据库测试整个API的端到端。

我们尝试了这个:

class SessionControllerIntegrationSpec extends IntegrationSpec {
    SessionController controller
    def setup() {
    }

    def cleanup() {
    }

    void "test login"() {
        controller = new SessionController()
        controller.request.contentType = 'application/json'
        controller.request.format = 'json'
        controller.response.format = 'json'

        when:
        controller.request.content =
                '{"user":"someuser","password":"somepass"}'.getBytes()

        def model = controller.loginPlayer()

        then:
        model != null
    }
}

但它总是返回null作为模型。

也尝试过:

class SessionControllerIntegrationSpec extends GroovyTestCase {
:
def sessionService
:
controller.sessionService = sessionService

根据传递“testing controllers with services

的说明

但这没有帮助 - 结果仍然无效。同时扩展GroovyTestCase意味着回到断言。

我们正在尝试做甚么可能吗?

我们看到有些人通过点击localhost的外部URL进行集成测试,例如:

class ExampleWebAppSpecification extends Specification {
    def "Should return 200 & a message with the input appended"() {

        setup:
             def primerEndpoint = new RESTClient( 'http://localhost:8080/' )
        when:
             def resp = primerEndpoint.get([ path: 'exampleendpoint', query : [ input : 'Get a hair cut' ]])
        then:
             with(resp) {
                 status == 200
                 contentType == "application/json"
             }
             with(resp.data) {
                 payload == "Something really important: Get a hair cut"
             }
    } }

这与使用jmeter或其他工具测试正在运行的服务器并没有太大区别,并且具有很多依赖性。

任何提示或建议?

更新1:

找到了一个这样做的例子

 assert controller.response.getStatus() == 200

在调试器中,controller.response.getStatus()返回405(我们的控制器永远不会返回的状态),controller.response.contentAsString返回“”。

当我们在调试器中运行测试时,永远不会调用Controllers代码。所以问题可能是grails根本没有注入SessionController。

更新2

猜测问题出在请求方法上,尝试添加:

    controller.request.requestMethod = HttpMethod.POST

然而,这仍然会产生405。

在REST控制器中,我们有:

static allowedMethods = [loginPlayer: "POST"]

如果我发表评论,我会收到预期的回复!

现在的问题是如何让测试使用POST(设置requestMethod似乎没有这样做),或者如果控制器处于测试模式下如何更改控制器以接受GET?

更新3 - 解决了!下面的工作代码:

类SessionControllerIntegrationSpec扩展了IntegrationSpec     def sessionService

class SessionControllerIntegrationSpec extends IntegrationSpec {
    SessionController controller

    void "test login"() {
        controller = new SessionController() // must manually create
        controller.sessionService = sessionService // must manually inject

        controller.request.contentType = 'application/json'
        controller.request.format = 'json'
        controller.response.format = 'json'
        controller.request.requestMethod = HttpMethod.POST
        controller.request.method = 'POST'


        when:
        controller.request.content =
                '{"user":"someuser","password":"somepass"}'.getBytes()

        then:
        assert controller.response.getStatus() == 200
        print "CONTENT: " + controller.response.contentAsString
        // now can use string search functions to check the JSON data returned.

0 个答案:

没有答案