我用Spring Boot, Spock和Rest Assured做了一个简单的测试。
package com.xxx.mako.rrhh.persona.infrastructure.controller
import com.xxx.mako.IntegrationTest
import com.xxx.mako.MakoApplication
import io.restassured.http.ContentType
import org.junit.experimental.categories.Category
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.TestPropertySource
import org.springframework.test.context.jdbc.Sql
import spock.lang.Specification
import io.restassured.RestAssured
import io.restassured.builder.ResponseSpecBuilder
import static io.restassured.RestAssured.*
import static org.hamcrest.Matchers.*
@ActiveProfiles("test")
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
classes = MakoApplication.class
)
@TestPropertySource(locations = "classpath:application-test.yml")
@Category(IntegrationTest.class)
@Sql(scripts = ["classpath:/createTablePersona.sql", "classpath:/insertTablePersona.sql"])
class PersonaRestAssuredSpec extends Specification {
final static URL_REST_SERVICE = "/mako/api/rest/personas/v1"
final static validToken = createHeaders("admin", "admin00")
final static invalidToken = createHeaders("dummy", "dummy")
final static SC_OK = 200
final static SC_UNAUTHORIZED = 401
@Value('${server.http.port}')
private int port
def setup() throws Exception {
RestAssured.port = port
}
def "findById"() {
given:
def request = given().accept(ContentType.JSON).header("Authorization", token)
when: "A rest for obtain the Persona object with idPersona, token"
def response = request.with().get(URL_REST_SERVICE + "/" + idPersona)
then: "We expected status and specification like in the parameterized list in where clause"
response.then().statusCode(status).spec(specification)
where:
idPersona || token || status || specification
1000 || invalidToken || SC_UNAUTHORIZED || expect().body("error", equalTo("Unauthorized"))
2 || validToken || SC_OK || expect().body("id", equalTo("2"))
}
private static String createHeaders(String username, String password) {
String auth = username + ":" + password
String encodedAuth = Base64.getEncoder().encodeToString(auth.getBytes("utf-8"))
String authHeader = "Basic " + encodedAuth
return authHeader
}
}
当我执行测试时,我得到这个错误:
Condition failed with Exception:
response.then().statusCode(status).spec(specification)
| | | | | |
| | | 401 | <io.restassured.internal.ResponseSpecificationImpl@6f6a7463 expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup@1e53135d assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure@7674a051 headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl@3a7704c contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar@6754ef00 config=io.restassured.config.RestAssuredConfig@619bd14c response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository@323e8306>
| | | groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl@51efdb72, io.restassured.internal.ResponseParserRegistrar@6754ef00, ...]
| | | Possible solutions: wait(), grep(), any()
| | | at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
| | | at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
| | | at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
| | | at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
| | | at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
| | <io.restassured.internal.ValidatableResponseImpl@76cbee13 responseSpec=io.restassured.internal.ResponseSpecificationImpl@59d09ff3 extractableResponse=io.restassured.internal.RestAssuredResponseImpl@51efdb72 response=io.restassured.internal.RestAssuredResponseImpl@51efdb72 config=io.restassured.config.RestAssuredConfig@619bd14c>
| <io.restassured.internal.ValidatableResponseImpl@76cbee13 responseSpec=io.restassured.internal.ResponseSpecificationImpl@59d09ff3 extractableResponse=io.restassured.internal.RestAssuredResponseImpl@51efdb72 response=io.restassured.internal.RestAssuredResponseImpl@51efdb72 config=io.restassured.config.RestAssuredConfig@619bd14c>
<io.restassured.internal.RestAssuredResponseImpl@51efdb72 logRepository=io.restassured.internal.log.LogRepository@7bc6b117 groovyResponse=io.restassured.internal.RestAssuredResponseOptionsGroovyImpl@2de07c57>
at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
Caused by: groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl@51efdb72, io.restassured.internal.ResponseParserRegistrar@6754ef00, ...]
Possible solutions: wait(), grep(), any()
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
... 1 more
Condition failed with Exception:
response.then().statusCode(status).spec(specification)
| | | | | |
| | | 200 | <io.restassured.internal.ResponseSpecificationImpl@7de43652 expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup@7fe0ca60 assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure@fdf029a headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl@63896cf7 contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar@3f838072 config=io.restassured.config.RestAssuredConfig@619bd14c response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository@46c9ee28>
| | | groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl@263e512e, io.restassured.internal.ResponseParserRegistrar@3f838072, ...]
| | | Possible solutions: wait(), grep(), any()
| | | at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
| | | at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
| | | at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
| | | at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
| | | at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
| | <io.restassured.internal.ValidatableResponseImpl@7c680fe1 responseSpec=io.restassured.internal.ResponseSpecificationImpl@288b8663 extractableResponse=io.restassured.internal.RestAssuredResponseImpl@263e512e response=io.restassured.internal.RestAssuredResponseImpl@263e512e config=io.restassured.config.RestAssuredConfig@619bd14c>
| <io.restassured.internal.ValidatableResponseImpl@7c680fe1 responseSpec=io.restassured.internal.ResponseSpecificationImpl@288b8663 extractableResponse=io.restassured.internal.RestAssuredResponseImpl@263e512e response=io.restassured.internal.RestAssuredResponseImpl@263e512e config=io.restassured.config.RestAssuredConfig@619bd14c>
<io.restassured.internal.RestAssuredResponseImpl@263e512e logRepository=io.restassured.internal.log.LogRepository@62c42a3 groovyResponse=io.restassured.internal.RestAssuredResponseOptionsGroovyImpl@6a8bcb64>
at com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec.findById(PersonaRestAssuredSpec.groovy:47)
Caused by: groovy.lang.MissingMethodException: No signature of method: io.restassured.internal.ContentParser.parse() is applicable for argument types: (io.restassured.internal.RestAssuredResponseImpl, io.restassured.internal.ResponseParserRegistrar...) values: [io.restassured.internal.RestAssuredResponseImpl@263e512e, io.restassured.internal.ResponseParserRegistrar@3f838072, ...]
Possible solutions: wait(), grep(), any()
at io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure.validate(ResponseSpecificationImpl.groovy:478)
at io.restassured.internal.ResponseSpecificationImpl.validate(ResponseSpecificationImpl.groovy:92)
at io.restassured.internal.ValidatableResponseOptionsImpl.spec(ValidatableResponseOptionsImpl.java:288)
at io.restassured.internal.ValidatableResponseImpl.spec(ValidatableResponseImpl.groovy:76)
... 1 more
我在gradle中有这个依赖项:
testRuntimeClasspath - Runtime classpath of compilation 'test' (target (jvm)).
+--- javax.inject:javax.inject:1
+--- org.springdoc:springdoc-openapi-ui:1.3.9
| +--- org.springdoc:springdoc-openapi-webmvc-core:1.3.9
| | +--- org.springdoc:springdoc-openapi-common:1.3.9
| | | +--- org.springframework.boot:spring-boot-autoconfigure:2.2.6.RELEASE -> 2.4.1
| | | | --- org.springframework.boot:spring-boot:2.4.1
| | | | +--- org.springframework:spring-core:5.3.2
| | | | | --- org.springframework:spring-jcl:5.3.2
| | | | --- org.springframework:spring-context:5.3.2
...
| | +--- org.junit.jupiter:junit-jupiter-api:5.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | +--- org.apiguardian:apiguardian-api:1.1.0
| | | +--- org.opentest4j:opentest4j:1.2.0
| | | --- org.junit.platform:junit-platform-commons:1.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | --- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.junit.jupiter:junit-jupiter-params:5.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | +--- org.apiguardian:apiguardian-api:1.1.0
| | | --- org.junit.jupiter:junit-jupiter-api:5.7.0 (*)
| | --- org.junit.jupiter:junit-jupiter-engine:5.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.junit.platform:junit-platform-engine:1.7.0
| | | +--- org.junit:junit-bom:5.7.0 (*)
| | | +--- org.apiguardian:apiguardian-api:1.1.0
| | | +--- org.opentest4j:opentest4j:1.2.0
| | | --- org.junit.platform:junit-platform-commons:1.7.0 (*)
| | --- org.junit.jupiter:junit-jupiter-api:5.7.0 (*)
| +--- org.mockito:mockito-core:3.6.28
| | +--- net.bytebuddy:byte-buddy:1.10.18 -> 1.10.10
| | +--- net.bytebuddy:byte-buddy-agent:1.10.18
| | --- org.objenesis:objenesis:3.1
| +--- org.mockito:mockito-junit-jupiter:3.6.28
| | +--- org.mockito:mockito-core:3.6.28 (*)
| | --- org.junit.jupiter:junit-jupiter-api:5.4.2 -> 5.7.0 (*)
| +--- org.skyscreamer:jsonassert:1.5.0
| | --- com.vaadin.external.google:android-json:0.0.20131108.vaadin1
| +--- org.springframework:spring-core:5.3.2 (*)
| +--- org.springframework:spring-test:5.3.2
| | --- org.springframework:spring-core:5.3.2 (*)
| --- org.xmlunit:xmlunit-core:2.7.0
+--- junit:junit:4.11
| --- org.hamcrest:hamcrest-core:1.3 -> 2.2
| --- org.hamcrest:hamcrest:2.2
+--- org.codehaus.groovy:groovy:3.0.7
+--- org.codehaus.groovy:groovy-json3.0.7 FAILED
+--- org.codehaus.groovy:groovy-xml3.0.7 FAILED
+--- org.spockframework:spock-core:2.0-M4-groovy-3.0
| +--- org.junit:junit-bom:5.7.0 (*)
| +--- org.codehaus.groovy:groovy:3.0.6 -> 3.0.7
| +--- org.junit.platform:junit-platform-engine -> 1.7.0 (*)
| +--- org.junit.platform:junit-platform-testkit -> 1.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | +--- org.assertj:assertj-core:3.16.1 -> 3.18.1
| | +--- org.opentest4j:opentest4j:1.2.0
| | --- org.junit.platform:junit-platform-launcher:1.7.0
| | +--- org.junit:junit-bom:5.7.0 (*)
| | +--- org.apiguardian:apiguardian-api:1.1.0
| | --- org.junit.platform:junit-platform-engine:1.7.0 (*)
| +--- org.hamcrest:hamcrest:2.2
| +--- org.jetbrains:annotations:19.0.0
| +--- org.ow2.asm:asm:9.0
| +--- net.bytebuddy:byte-buddy:1.10.16 -> 1.10.10
| +--- cglib:cglib-nodep:3.3.0
| --- org.objenesis:objenesis:3.1
+--- org.spockframework:spock-spring:2.0-M4-groovy-3.0
| +--- org.junit:junit-bom:5.7.0 (*)
| +--- org.codehaus.groovy:groovy:3.0.6 -> 3.0.7
| +--- org.spockframework:spock-core:2.0-M4-groovy-3.0 (*)
| +--- org.springframework:spring-test:4.3.5.RELEASE -> 5.3.2 (*)
| +--- org.springframework:spring-beans:4.3.5.RELEASE -> 5.3.2 (*)
| --- org.springframework:spring-context:4.3.5.RELEASE -> 5.3.2 (*)
+--- org.hamcrest:hamcrest-core:2.2 (*)
+--- io.rest-assured:rest-assured:4.3.3
| +--- org.codehaus.groovy:groovy:3.0.7
| +--- org.codehaus.groovy:groovy-xml:3.0.7 -> 2.5.14
| | --- org.codehaus.groovy:groovy:2.5.14 -> 3.0.7
| +--- org.apache.httpcomponents:httpclient:4.5.3 -> 4.5.13
| | +--- org.apache.httpcomponents:httpcore:4.4.13 -> 4.4.14
| | --- commons-codec:commons-codec:1.11 -> 1.15
| +--- org.apache.httpcomponents:httpmime:4.5.3 -> 4.5.13
| | --- org.apache.httpcomponents:httpclient:4.5.13 (*)
| +--- org.hamcrest:hamcrest:2.1 -> 2.2
| +--- org.ccil.cowan.tagsoup:tagsoup:1.2.1
| +--- io.rest-assured:json-path:4.3.3
| | +--- org.codehaus.groovy:groovy-json:3.0.7 -> 2.5.14
| | | --- org.codehaus.groovy:groovy:2.5.14 -> 3.0.7
| | +--- org.codehaus.groovy:groovy:3.0.7
| | --- io.rest-assured:rest-assured-common:4.3.3
| | +--- org.codehaus.groovy:groovy:3.0.7
| | --- org.apache.commons:commons-lang3:3.11
| --- io.rest-assured:xml-path:4.3.3
| +--- org.codehaus.groovy:groovy-xml:3.0.7 -> 2.5.14 (*)
| +--- org.codehaus.groovy:groovy:3.0.7
| +--- io.rest-assured:rest-assured-common:4.3.3 (*)
| +--- org.apache.commons:commons-lang3:3.11
| +--- org.ccil.cowan.tagsoup:tagsoup:1.2.1
| +--- jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (*)
| --- com.sun.xml.bind:jaxb-impl:2.3.3
| --- jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (*)
+--- io.rest-assured:rest-assured-common:4.3.3 (*)
+--- io.rest-assured:json-path:4.3.3 (*)
+--- io.rest-assured:xml-path:4.3.3 (*)
+--- net.bytebuddy:byte-buddy:1.10.10
--- org.objenesis:objenesis:3.1
我不明白为什么出现这个版本:
| +--- org.codehaus.groovy:groovy-xml:3.0.7 -> 2.5.14 (*)
+--- org.codehaus.groovy:groovy-json:3.0.7 -> 2.5.14
当我显式地放置3.0.7。我不明白上一个版本的Rest Assured和Groovy 3之间存在这样的问题。提前感谢您的解决方案。
只是猜测,但看起来您忘记了artifactId
和version
之间的:
。
+--- org.codehaus.groovy:groovy-json3.0.7 FAILED
+--- org.codehaus.groovy:groovy-xml3.0.7 FAILED
org.codehaus.groovy:groovy-json3.0.7
应为org.codehaus.groovy:groovy-json:3.0.7
。
如果没有MCVE,我只能从我的水晶球中收集到这么多。
是我的错,我在gradle文件中犯了':'这个依赖项。
:
testImplementation("org.codehaus.groovy:groovy:${groovyVersion}")
testImplementation("org.codehaus.groovy:groovy-json:${groovyVersion}")
testImplementation("org.codehaus.groovy:groovy-xml:${groovyVersion}")
testImplementation("org.spockframework:spock-core:${groovySpockVersion}")
testImplementation("org.spockframework:spock-spring:${groovySpockVersion}")
// optional dependencies for using Spock
现在测试运行正常:
> Configure project :
executing dev liquibase
executing int liquibase
executing pre liquibase
executing pro liquibase
> Task :test
com.xxx.mako.rrhh.persona.infrastructure.controller.PersonaRestAssuredSpec
? findById [idPersona: 1000, token: Basic ZHVtbXk6ZHVtbXk=, status: 401, specification: <io.restassured.internal.ResponseSpecificationImpl@30476d7a expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup@4903a252 assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure@339460d8 headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl@7f3c8b4b contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar@41c555c config=io.restassured.config.RestAssuredConfig@50d966bf response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository@40db5edc>, #0] (11s)
? findById [idPersona: 2, token: Basic YWRtaW46YWRtaW4wMA==, status: 200, specification: <io.restassured.internal.ResponseSpecificationImpl@6dc2c46b expectedStatusCode=null expectedStatusLine=null bodyMatchers=io.restassured.assertion.BodyMatcherGroup@cd2d276 assertionClosure=io.restassured.internal.ResponseSpecificationImpl$HamcrestAssertionClosure@6f2591d5 headerAssertions=[] cookieAssertions=[] requestSpecification=io.restassured.internal.RequestSpecificationImpl@7d5a6a85 contentType=null restAssuredResponse=null bodyRootPath= rpr=io.restassured.internal.ResponseParserRegistrar@6c008d9 config=io.restassured.config.RestAssuredConfig@50d966bf response=null expectedResponseTime=null responseLogDetail=null forceDisableEagerAssert=false contentParser=null logRepository=io.restassured.internal.log.LogRepository@5ff3ba6a>, #1] (1.5s)
? findById (48.9s)
非常感谢@Leonard brnings