Spock & Spring Boot 集成测试

son*_*rin 2 groovy spock spring-boot

我有一个 Spring Boot 1.5.1.RELEASE 项目,使用 Spock 1.1 进行集成测试。我有一个基本控制器:

\n\n
@RestController("/words")\npublic class WordsController {\n\n   @RequestMapping(method = RequestMethod.GET)\n   @ResponseBody\n   public ResponseEntity getAllWords() {\n      return ResponseEntity\n         .status(HttpStatus.OK)\n         .contentType(MediaType.APPLICATION_JSON)\n         .body("Your list of words go here");\n   }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我正在尝试使用以下方法测试端点:

\n\n
@ContextConfiguration(classes = MyApplication.class)\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)\n@ActiveProfiles("test")\nclass WordsControllerTest extends Specification {\nRESTClient restClient = new RESTClient("http://localhost:3000", ContentType.JSON)\n\n    def "test the GET endpoint is available"() {\n        when:\n        def response = restClient.get(\n                path: \'/words\',\n                requestContentType: JSON\n        )\n\n        then:\n        response.status == 200\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的应用程序主类:

\n\n
@SpringBootApplication\npublic class MyApplication {\n\n    public static void main(String[] args) {\n        SpringApplication.run(MyApplication.class, args);\n    }\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是当我运行这个时,我收到一个非常奇怪的错误:

\n\n
\n

groovyx.net.http.RESTClient:解析\n \'application/json\' 响应时出错

\n\n

groovy.json.JsonException: 无法确定当前字符,\n 它不是字符串、数字、数组或对象

\n\n

当前读取的字符为\'Y\',int值为89 无法\n确定当前字符,它不是字符串、数字、数组、或\n 对象行号 1 索引号 0 您的单词列表位于\n\n\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef \xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf \xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd \n ^ at\n groovy.json.internal.JsonParserCharArray.decodeValueInternal(JsonParserCharArray.java:206)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.json。Internal.JsonParserCharArray.decodeValue(JsonParserCharArray.java:157)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.json.internal.JsonParserCharArray.decodeFromChars(JsonParserCharArray.java:46)\ n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.json.internal.JsonParserCharArray.parse(JsonParserCharArray.java:384)\n ~[groovy-all-2.4.7.jar: 2.4.7] 在\n groovy.json.internal.BaseJsonParser.parse(BaseJsonParser.java:128)\n ~[groovy-all-2.4.7.jar:2.4.7] 在\n groovy.json.JsonSlurper。解析(JsonSlurper.java:221)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovyx.net.http.ParserRegistry.parseJSON(ParserRegistry.java:280)\n ~[http -builder-0.7.1.jar:na] at\n sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)\n ~[na:1.8.0_40] at\n sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 62)\n ~[na:1.8.0_40] at\n sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\n ~[na:1.8.0_40] at java.lang.reflect.Method.invoke( Method.java:497)\n ~[na:1.8.0_40] at\n org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)\n ~[groovy-all-2.4.7.jar :2.4.7] at\n groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod (MetaClassImpl.java:1215)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1082)\n ~[groovy-all- 2.4.7.jar:2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy。 lang.Closure.call(Closure.java:414)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang.Closure.call(Closure.java:430)\n ~ [groovy-all-2.4.7.jar:2.4.7]2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1215)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod( MetaClassImpl.java:1082)\n ~[groovy-all-2.4.7.jar:2.4.7] 在\n groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)\n ~[groovy-all-2.4 .7.jar:2.4.7] at\n groovy.lang.Closure.call(Closure.java:414)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang .Closure.call(Closure.java:430)\n ~[groovy-all-2.4.7.jar:2.4.7]2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1215)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang.MetaClassImpl.invokeMethod( MetaClassImpl.java:1082)\n ~[groovy-all-2.4.7.jar:2.4.7] 在\n groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1024)\n ~[groovy-all-2.4 .7.jar:2.4.7] at\n groovy.lang.Closure.call(Closure.java:414)\n ~[groovy-all-2.4.7.jar:2.4.7] at\n groovy.lang .Closure.call(Closure.java:430)\n ~[groovy-all-2.4.7.jar:2.4.7]

\n
\n\n

不确定它是否有什么不同,但这是我的 gradle 文件的一部分:

\n\n
compile(\'org.springframework.boot:spring-boot-starter-data-jpa\')\ncompile(\'org.springframework.boot:spring-boot-devtools\')\ncompile("org.springframework.boot:spring-boot-starter-web:${springBootVersion}")\nruntime(\'com.h2database:h2\')\ncompile group: \'org.codehaus.groovy.modules.http-builder\', name: \'http-builder\', version: \'0.7.1\'\ntestCompile(\'org.springframework.boot:spring-boot-starter-test\')\ntestCompile(\'org.spockframework:spock-core:1.1-groovy-2.4-rc-2\')\ntestCompile(\'org.spockframework:spock-spring:1.1-groovy-2.4-rc-2\')\ntestCompile "org.hamcrest:hamcrest-core:1.2"\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不确定为什么 JSON 没有正确发送或接收。

\n

Opa*_*pal 6

将端点标记为返回媒体类型是不够的application/json。您还需要返回有效的JSON 内容,其中:

"Your list of words go here"
Run Code Online (Sandbox Code Playgroud)

不是。

如果需要返回列表,请写入:

return ResponseEntity
   .status(HttpStatus.OK)
   .contentType(MediaType.APPLICATION_JSON)
   .body("{\"words\": [\"one\", \"two\"]}");
Run Code Online (Sandbox Code Playgroud)

或一条简单的消息:

return ResponseEntity
   .status(HttpStatus.OK)
   .contentType(MediaType.APPLICATION_JSON)
   .body("{\"msg\": \"content\"");
Run Code Online (Sandbox Code Playgroud)

Spring可以自动将POJO映射到JSON负载,看看@ResponseBody