【问题标题】:How do I configure mime types in a grails Spock test?如何在 grails Spock 测试中配置 mime 类型?
【发布时间】:2014-08-26 22:39:04
【问题描述】:

Grails 2.3.10.

如何为 Grails Spock 测试中的内容类型协商配置可用的 mime 类型?

当我试图告诉控制器生成 JSON 内容时,它似乎想要返回一个 HTTP 406 错误。我在我的测试代码中发送 Accept 标头;但是,解析器无法匹配它,因为 HTML 是唯一配置的 MIME 类型。

我的用例...

我使用 Grails respond 方法实现了一个控制器操作,该方法可以返回 JSON 响应。当我使用 REST API 调用到达端点时,我能够取回 JSON 输出(即使没有指定 Accept 标头)。

控制器代码:

@Transactional(readOnly = true)
class MyObjectController {
    static allowedMethods = [save: 'POST']
    static responseFormats = ['json']
    def myService

    @Transactional
    def save(MyObject obj) {
        obj.validate()
        if (obj.hasErrors()) {
            respond obj.getErrors(), [status: BAD_REQUEST]
        }

        myService.addNewCustomer(obj)

        respond obj, [formats: responseFormats]
    }
}

还有我的测试代码:

@TestFor(MyObjectController)
class MyObjectControllerSpec extends Specification {
    def setup() {
    }

    def cleanup() {
    }

    void "test save - json success"() {
        given:
        def myObj = new MyObject()
        controller.myService= Mock(MyObjectService)

        when:
        request.addHeader "Accept", "application/json"
        controller.save(individual)

        then:
        response.status == HttpStatus.CREATED.value()
        response.text == "{}"   //.text is giving me an empty string
        response.json.x == x    //.json throws an exception (parsing an empty string)
    }
}

我已在调试器中验证 obj 具有有效值,并且在控制器操作的最后一行调用了 respond 方法。

我发现在 Grails ResponseMimeTypesApi 类中,DefaultAcceptHeaderParser 仅使用 HTML mime 类型构建。即使正确读取了 JSON 接受标头,DefaultAcceptHeaderParser 也无法理解它,因为没有配置 mime 类型。

如何在我的单元测试规范中控制发送到 ResponseMimeTypesApi 的 mime 类型?

编辑

我也尝试过设置 response.format 属性,如this answer 中所建议的那样;但是,无济于事。

【问题讨论】:

    标签: unit-testing grails controller spock grails-2.3


    【解决方案1】:

    如果您为request.json 分配一个值,将设置内容类型。您还可以使用request.contentType = 'application/json'request.contentType = JSON_CONTENT_TYPE 之类的内容显式设置内容类型。有关单元测试中可用的内容类型常量的列表,请参阅http://grails.org/doc/latest/guide/testing.html#unitTestingControllers 下的“测试 Mime 类型处理”部分。

    另一个要查看的资源是https://github.com/grails/grails-core/blob/4f8d1a605cde60a4a00021102959578dae8bc5a8/grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding/json/JsonBindingSpec.groovyhttps://github.com/grails/grails-core/blob/801d507cf3fec5866baa14f6d6b0acd05aa5fb56/grails-test-suite-web/src/test/groovy/org/codehaus/groovy/grails/web/binding/xml/XmlBindingSpec.groovy 的单元测试。

    希望对你有帮助。

    编辑:

    澄清一下……

    我提到了为request.json 赋值。您分配给它的值当然是 JSON,而不是内容类型。像这样……

    request.json = '''
    {
        "name": "Douglas", "age": "42"
    }
    '''
    

    当你这样做时,内容类型会自动设置。

    【讨论】:

    • 杰夫,感谢您的回复;但是,这个问题是关于响应的 MIME 类型,而不是关于绑定请求数据。您提供的两个示例链接没有显示这是如何完成的,我无法从 Grails 文档中弄清楚。
    • 道歉。那是我的错。
    【解决方案2】:

    我发现我可以通过将单元测试转换为集成测试来编写我想要的测试。

    1. 将测试移至 /integration 路径。
    2. 更改测试规范以扩展 IntegrationSpec
    3. @Autowire 被测类,而不是使用 @TestFor
    4. 设置 controller.response.format = 'json' 并调用 controller.request.addHeader 'Accept', 'application/json'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 2012-03-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多