配置客户端合同云测试的难度

时间:2017-12-08 15:48:08

标签: spring spring-boot groovy spring-restcontroller spring-cloud-contract

我正在尝试使用spring cloud合约来测试我的REST API。我按照本教程https://cloud.spring.io/spring-cloud-contract/中描述的说明进行操作 我正在使用groovy编写单基础测试类。

My Rest Controller类:

@RestController
@RequestMapping(headers = arrayOf("X-API-Version=v2"))
class FileControllerV2(val storageService: StorageService) {

    @PostMapping("/contracts.upload")
    fun upload(@RequestParam file: MultipartFile, principal: Principal): FileNameResponse {
        return storageService.save(file, principal.name)
    }

    @GetMapping("/contracts.download/{filename:.+}")
    fun download(@PathVariable filename: String): ResponseEntity<*> {
        return storageService.download(filename)
    }

    @GetMapping("/contracts.info/{filename:.+}")
    fun info(@PathVariable filename: String): ResponseEntity<*> {
        return storageService.info(filename)
    }
}

我的合约存根

package contracts.upload

import org.springframework.cloud.contract.spec.Contract

Contract.make {
    request {
        method 'POST'
        url '/contracts.upload'
        multipart(
                file: named(
                        name: $(c(regex(nonEmpty())), p('filename')),
                        content: $(c(regex(nonEmpty())), p('content'))),
                principal : $(regex('.+'))
        )

        headers {
        contentType('multipart/form-data; boundary=----WebKitFormBoundaryBTX23kTw0Z5a5bsF')
        header('X-API-Version','v2')

    }
    }
    response {
        status 200
        body([
                filename: 'filename'
        ])
        headers {
            contentType('application/json')
        }
    }
}

我的基础课:

class UploadBase extends Specification {

    private StorageService storageService = Mock()

    def setup() {
        given:
        RestAssuredMockMvc.standaloneSetup(new FileControllerV2(storageService))
    }
}

建成之后我有了以下的堆栈跟踪

15:49:59.550 [Test worker] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
15:49:59.554 [Test worker] DEBUG org.springframework.core.env.StandardEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
15:49:59.554 [Test worker] DEBUG org.springframework.core.env.StandardEnvironment - Initialized StandardEnvironment with PropertySources [systemProperties,systemEnvironment]
15:49:59.681 [Test worker] DEBUG org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Looking for request mappings in application context: org.springframework.test.web.servlet.setup.StubWebApplicationContext@5c4dadd7
15:49:59.712 [Test worker] DEBUG org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - 3 request handler methods found on class com.project.fstorage.storage.FileControllerV2: {public org.springframework.http.ResponseEntity com.project.fstorage.storage.FileControllerV2.download(java.lang.String)={[/contracts.download/{filename:.+}],methods=[GET],headers=[X-API-Version=v2]}, public com.project.fstorage.response.FileNameResponse com.project.fstorage.storage.FileControllerV2.upload(org.springframework.web.multipart.MultipartFile,java.security.Principal)={[/contracts.upload],methods=[POST],headers=[X-API-Version=v2]}, public org.springframework.http.ResponseEntity com.project.fstorage.storage.FileControllerV2.info(java.lang.String)={[/contracts.info/{filename:.+}],methods=[GET],headers=[X-API-Version=v2]}}
15:49:59.723 [Test worker] INFO org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Mapped "{[/contracts.download/{filename:.+}],methods=[GET],headers=[X-API-Version=v2]}" onto public org.springframework.http.ResponseEntity<?> com.project.fstorage.storage.FileControllerV2.download(java.lang.String)
15:49:59.725 [Test worker] INFO org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Mapped "{[/contracts.upload],methods=[POST],headers=[X-API-Version=v2]}" onto public com.project.fstorage.response.FileNameResponse com.project.fstorage.storage.FileControllerV2.upload(org.springframework.web.multipart.MultipartFile,java.security.Principal)
15:49:59.725 [Test worker] INFO org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Mapped "{[/contracts.info/{filename:.+}],methods=[GET],headers=[X-API-Version=v2]}" onto public org.springframework.http.ResponseEntity<?> com.project.fstorage.storage.FileControllerV2.info(java.lang.String)
15:49:59.994 [Test worker] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Slf4jLoggerProvider
15:49:59.995 [Test worker] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 5.3.5.Final
15:50:00.015 [Test worker] DEBUG org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver - Found javax.persistence.Persistence on classpath containing 'getPersistenceUtil'. Assuming JPA 2 environment. Trying to instantiate JPA aware TraversableResolver
15:50:00.016 [Test worker] DEBUG org.hibernate.validator.internal.engine.resolver.DefaultTraversableResolver - Instantiated JPA aware TraversableResolver of type org.hibernate.validator.internal.engine.resolver.JPATraversableResolver.
15:50:00.025 [Test worker] DEBUG org.hibernate.validator.internal.engine.ConfigurationImpl - Setting custom MessageInterpolator of type org.springframework.validation.beanvalidation.LocaleContextMessageInterpolator
15:50:00.026 [Test worker] DEBUG org.hibernate.validator.internal.engine.ConfigurationImpl - Setting custom ParameterNameProvider of type com.sun.proxy.$Proxy36
15:50:00.028 [Test worker] DEBUG org.hibernate.validator.internal.xml.ValidationXmlParser - Trying to load META-INF/validation.xml for XML based Validator configuration.
15:50:00.029 [Test worker] DEBUG org.hibernate.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via TCCL
15:50:00.029 [Test worker] DEBUG org.hibernate.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via Hibernate Validator's class loader
15:50:00.030 [Test worker] DEBUG org.hibernate.validator.internal.xml.ValidationXmlParser - No META-INF/validation.xml found. Using annotation based configuration only.
15:50:00.068 [Test worker] INFO org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter - Looking for @ControllerAdvice: org.springframework.test.web.servlet.setup.StubWebApplicationContext@5c4dadd7
15:50:00.096 [Test worker] DEBUG org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Looking for exception mappings: org.springframework.test.web.servlet.setup.StubWebApplicationContext@5c4dadd7
15:50:00.113 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Initializing servlet ''
15:50:00.122 [Test worker] DEBUG org.springframework.web.context.support.StandardServletEnvironment - Adding [servletConfigInitParams] PropertySource with lowest search precedence
15:50:00.122 [Test worker] DEBUG org.springframework.web.context.support.StandardServletEnvironment - Adding [servletContextInitParams] PropertySource with lowest search precedence
15:50:00.125 [Test worker] DEBUG org.springframework.web.context.support.StandardServletEnvironment - Adding [systemProperties] PropertySource with lowest search precedence
15:50:00.125 [Test worker] DEBUG org.springframework.web.context.support.StandardServletEnvironment - Adding [systemEnvironment] PropertySource with lowest search precedence
15:50:00.125 [Test worker] DEBUG org.springframework.web.context.support.StandardServletEnvironment - Initialized StandardServletEnvironment with PropertySources [servletConfigInitParams,servletContextInitParams,systemProperties,systemEnvironment]
15:50:00.125 [Test worker] INFO org.springframework.mock.web.MockServletContext - Initializing Spring FrameworkServlet ''
15:50:00.125 [Test worker] INFO org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization started
15:50:00.127 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Unable to locate MultipartResolver with name 'multipartResolver': no multipart request handling provided
15:50:00.127 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using LocaleResolver [org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver@186a2f7]
15:50:00.128 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using ThemeResolver [org.springframework.web.servlet.theme.FixedThemeResolver@71cabba8]
15:50:00.128 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using RequestToViewNameTranslator [org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator@53aff6f3]
15:50:00.128 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Using FlashMapManager [org.springframework.web.servlet.support.SessionFlashMapManager@5138be3e]
15:50:00.128 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Published WebApplicationContext of servlet '' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.]
15:50:00.128 [Test worker] INFO org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization completed in 3 ms
15:50:00.128 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Servlet '' configured successfully
15:50:00.175 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - DispatcherServlet with name '' processing POST request for [/contracts.upload]
15:50:00.177 [Test worker] DEBUG org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Looking up handler method for path /contracts.upload
15:50:00.179 [Test worker] DEBUG org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping - Did not find handler method for [/contracts.upload]
15:50:00.179 [Test worker] WARN org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [/contracts.upload] in DispatcherServlet with name ''
15:50:00.179 [Test worker] DEBUG org.springframework.test.web.servlet.TestDispatcherServlet - Successfully completed request

Condition not satisfied:

response.statusCode == 200
|        |          |
|        404        false
io.restassured.module.mockmvc.internal.MockMvcRestAssuredResponseImpl@77920871

Condition not satisfied:

response.statusCode == 200
|        |          |
|        404        false
io.restassured.module.mockmvc.internal.MockMvcRestAssuredResponseImpl@77920871

    at org.springframework.cloud.contract.verifier.tests.UploadSpec.validate_shouldSaveFile(UploadSpec.groovy:25)

我不知道是什么原因导致无法识别这些端点。

被修改 我添加了生成的测试

package org.springframework.cloud.contract.verifier.tests

import com.jayway.jsonpath.DocumentContext
import com.jayway.jsonpath.JsonPath
import com.project.fstorage.UploadBase

import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson
import static io.restassured.module.mockmvc.RestAssuredMockMvc.*
import static org.springframework.cloud.contract.verifier.assertion.SpringCloudContractAssertions.assertThat

class UploadSpec extends UploadBase {
def validate_shouldSaveFile() throws Exception {
    given:
    def request = given()
            .header("Content-Type", "multipart/form-data; boundary=----WebKitFormBoundaryBTX23kTw0Z5a5bsF")
            .header("X-API-Version", "v2")
            .multiPart('file', 'filename', 'content'.bytes)
            .param('principal', 'レ')

    when:
    def response = given().spec(request)
            .post("/contracts.upload")

    then:
    response.statusCode == 200
    response.header('Content-Type') ==~ java.util.regex.Pattern.compile('application/json.*')
    and:
    DocumentContext parsedJson = JsonPath.parse(response.body.asString())
    assertThatJson(parsedJson).field("['filename']").isEqualTo("filename")
}

}

1 个答案:

答案 0 :(得分:0)

如果使用安全性,最好设置正常的上下文以保证或手动添加过滤器。

设置Web应用程序上下文的示例

@Autowired
private WebApplicationContext context;

@Before
public void setup() {
    RestAssuredMockMvc.webAppContextSetup(context);
}