如何在Grails Spock测试中配置mime类型?

时间:2014-08-26 22:39:04

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

Grails 2.3.10。

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

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

我的用例......

我已使用Grails 响应方法实现了一个控制器操作,该方法可以返回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中所述;但是,无济于事。

2 个答案:

答案 0 :(得分:0)

如果您为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"
}
'''

执行此操作时,会自动设置内容类型。

答案 1 :(得分:0)

我发现我可以通过从一个单元转换到一个集成测试来编写我想要的测试。

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