有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

使用Pact的rest JAVA契约测试(CDC)

我正在尝试为此服务编写合同测试:

    @RestController
    @RequestMapping(path = "/api/form")
    public class FormController {

        private RestOperations restOperations;

        @Autowired
        public FormController(RestOperations restOperations) {
            this.restOperations = restOperations;
        }


        @PostMapping(path = "/submit", consumes = MediaType.APPLICATION_JSON_UTF8_VALUE, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
        public ResponseEntity<SubmitFormResponse> submitForm(@RequestBody @Valid SubmitFormCommand submitFormCommand) {
            return restOperations.postForEntity("http://127.0.0.1:9000/api/form/submit", submitFormCommand, SubmitFormResponse.class);
        }
}

SubmitFormCommand仅包含字符串“消息”,而SubmitFormResponse包含布尔值“成功”

此服务的我的RestClient:

@Component
public class FormControllerClient {

    @Autowired
    private RestOperations restOperations;

    public ResponseEntity<SubmitFormResponse> submitForm(SubmitFormCommand submitFormCommand) {
        HttpEntity<SubmitFormCommand> request = new HttpEntity<>(submitFormCommand);
        return restOperations.exchange("http://localhost:1234/api/form/submit", HttpMethod.POST, request, SubmitFormResponse.class);
    }

消费者的合同测试类如下所示:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ContactFormClientTest {

    @Rule
    public PactProviderRuleMk2 pactProviderRuleMk2 = new PactProviderRuleMk2("formservice", "localhost", 1234, this);
    @Autowired
    private FormControllerClient formControllerClient;

    @Pact(state = "provider accets submit contact form", provider = "formservice", consumer = "formclient")
    public RequestResponsePact submitFormPact(PactDslWithProvider builder) {
        return builder
                .given("provider accetps form submit")
                .uponReceiving("a request to POST form")
                .path("/api/form/submit")
                .method("POST")
                .willRespondWith()
                .status(200)
                .matchHeader("Content-Type", "application/json;charset=UTF-8")
                .body(new PactDslJsonBody()
                        .stringType("message", "TestMessage"))
                .toPact();
    }

    @Test
    @PactVerification(fragment = "submitFormPact")
    public void verifySubmitFormPact() {
        SubmitFormCommand submitFormCommand = new SubmitFormCommand("TestMessage");
        ResponseEntity<SubmitFormResponse> response = formControllerClient.submitForm(submitFormCommand);
        assertNotNull(response);

    }
}

每次我运行测试时,它都会说“连接被拒绝”,我不明白我的设置有什么问题,在这种情况下,我的FormController将成为消费者,因为它调用另一个服务来提交表单

在pom中插入插件。用于构建Pact文件的xml如下所示:

            <plugin>
                <!-- mvn pact:publish  -->
                <groupId>au.com.dius</groupId>
                <artifactId>pact-jvm-provider-maven_2.11</artifactId>
                <version>3.5.10</version>
                <configuration>
                    <pactDirectory>../pacts</pactDirectory>
                    <pactBrokerUrl>http://localhost:1234</pactBrokerUrl>
                    <projectVersion>${project.version}</projectVersion>
                </configuration>
            </plugin>

共 (1) 个答案

  1. # 1 楼答案

    问题是,您正在将请求主体放入响应中。你的协议应该是这样的:

    @Pact(state = "provider accets submit contact form", provider = "formservice", consumer = "formclient")
        public RequestResponsePact submitFormPact(PactDslWithProvider builder) {
            return builder
                    .given("provider accetps form submit")
                    .uponReceiving("a request to POST form")
                    .path("/api/form/submit")
                    .method("POST")
                    .body(new PactDslJsonBody()
                            .stringType("message", "TestMessage"))
                    .willRespondWith()
                    .status(200)
                    .matchHeader("Content-Type", "application/json;charset=UTF-8")
                    .body(new PactDslJsonBody()
                            .booleanType("sucess", true))
                    .toPact();
        }