当前位置: 首页 > 知识库问答 >
问题:

如何生成spring restdocs和Pact。来自junit测试的io协议?

慎志国
2023-03-14

使用Spring boot和mockmvc,我有以下@beforeeach方法的测试类:

@BeforeEach
void setUp(WebApplicationContext context,
           RestDocumentationContextProvider restDocumentation) {
    MockMvcRestDocumentationConfigurer configurer = documentationConfiguration(restDocumentation);
    configurer.operationPreprocessors()
            .withRequestDefaults(prettyPrint())
            .withResponseDefaults(prettyPrint());
    configurer.snippets()
            .withDefaults(
                    httpRequest(),
                    httpResponse()
            );
    this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
            .apply(configurer)
            .build();

以及以下测试方法:

@Test
void createAdminHttpRequest() throws Exception {
    var adminDTO = HandlerTestObjectGenerator.createFixedAdminDTO();

    mockMvc.perform(
            RestDocumentationRequestBuilders
                    .post("/api/admins")
                    .content(objectMapper.writeValueAsString(adminDTO))
                    .contentType(MediaType.APPLICATION_JSON_UTF8)
    ).andExpect(status().isCreated())
            .andDo(document("create-admin",
                    preprocessRequest(),
                    preprocessResponse(),
                    requestFields(
                            usernameFieldDescriptor,
                            passwordFieldDescriptor,
                            rolesFieldDescriptor
                    ),
                    responseFields(
                            admin_adminIdFieldDescriptor,
                            admin_usernameFieldDescriptor,
                            admin_rolesFieldDescriptor
                    ),
                    SpringCloudContractRestDocs.dslContract(),
            ));
}


但是对于前端(反应)测试,我需要生成Pact.io合约,它是独立于框架的。

问题
那么,我的问题是是否可以同时生成spring rest文档和pact。使用单一测试方法的io pact?

我的研究发现,到目前为止,Pact是使用自己的rest生成器从带注释的方法生成的<此外,我发现了以下对话:https://gitter.im/spring-cloud/spring-cloud-contract/archives/2018/08/06我试图实现自己的maven插件,将groovy契约转换为契约,但BodyConverter类中似乎有错误,我得到了以下异常:

java.lang.UnsupportedOperationException: use the array(String name) form
at au.com.dius.pact.consumer.dsl.PactDslJsonBody.array(PactDslJsonBody.java:673)

我的maven插件代码示例:初始化:

private PactContractConverter pactContractConverter = new PactContractConverter();
private ContractVerifierDslConverter contractDslConverter = new ContractVerifierDslConverter();

转换:

private void processFiles(List<File> contractFiles) throws Exception {
        for(File file : contractFiles) {
            logger.info("Processing " + file.getAbsolutePath());
            Collection<Contract> contracts = contractDslConverter.convertFrom(file);
            Collection<Pact> pacts = pactContractConverter.convertTo(contracts);

            String jsonPacts = mapper.writeValueAsString(pactContractConverter.store(pacts));
            File pactsFile = new File(outputDir, file.getName() + "_pact.json");
            FileUtils.writeByteArrayToFile(pactsFile, jsonPacts.getBytes());
            logger.info("Generated pact file: " + pactsFile.getAbsolutePath());
        }
    }

但是我得到了上面提到的例外。有一个对方法的直接调用,它抛出不支持操作异常(UnsupportedOperationException)。我找到了另一个方法数组(字符串名),但它似乎不是从转换器代码中调用的。

共有1个答案

闾丘才哲
2023-03-14

让我们从这句话开始:

但对于前端(react)测试,我需要生成Pact。io契约,独立于框架

您可以在多语言世界中使用Spring Cloud Contract。只需使用Docker(https://spring.io/blog/2018/02/13/spring-cloud-contract-in-a-polyglot-world)和https://cloud.spring.io/spring-cloud-static/spring-cloud-contract/2.2.0.RELEASE/reference/html/docker-project.html

回到你的问题

所以,我的问题是,是否可以使用单个@Test方法生成SpringRest文档和pact.io协议?

让我们用另一种方式来做……既然你已经有了DSL,我想你也想得到Pact文件。如果您查看本节下的文档(https://cloud.spring.io/spring-cloud-static/spring-cloud-contract/2.2.0.RELEASE/reference/html/howto.html#how-要从scc生成pact),您将看到您问题的确切答案。添加一个插件就足够了,在您的测试生成DSL后,DSL会将这些DSL转换为其他内容,例如Pact文件。

使用Maven插件的示例

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.6.0</version>
    <executions>
        <execution>
            <id>convert-dsl-to-pact</id>
            <phase>process-test-classes</phase>
            <configuration>
                <classpathScope>test</classpathScope>
                <mainClass>
                    org.springframework.cloud.contract.verifier.util.ToFileContractsTransformer
                </mainClass>
                <arguments>
                    <argument>
                        org.springframework.cloud.contract.verifier.spec.pact.PactContractConverter
                    </argument>
                    <argument>${project.basedir}/target/pacts</argument>
                    <argument>
                        ${project.basedir}/src/test/resources/contracts
                    </argument>
                </arguments>
            </configuration>
            <goals>
                <goal>java</goal>
            </goals>
        </execution>
    </executions>
</plugin>

如果您修改${project.basedir}/src/test/resources/contracts以指向从REST文档测试中转储DSL的位置,您将获得转储到${project.basedir}/target/pacts的PACT文件。下面是Gradle的一个类似示例

task convertContracts(type: JavaExec) {
    main = "org.springframework.cloud.contract.verifier.util.ToFileContractsTransformer"
    classpath = sourceSets.test.compileClasspath
    args("org.springframework.cloud.contract.verifier.spec.pact.PactContractConverter",
            "${project.rootDir}/build/pacts", "${project.rootDir}/src/test/resources/contracts")
}

 类似资料:
  • 我是新来的。我的项目是Java项目。我通读了pact文档,找到了github项目https://github.com/dius/pact-jvm/tree/master/pact-jvm-consumer-junit,我将其导入到eclipse IDE中。我被困在这里了。1.首先运行哪个测试。ExampleJavaConsumerPactRuleTest还是ExampleJavaConsumerP

  • 本文向大家介绍jmeter如何自动生成测试报告,包括了jmeter如何自动生成测试报告的使用技巧和注意事项,需要的朋友参考一下 1、准备.jmx脚本文件 2、在脚本文件路径下执行cmd命令: 参数解析:   ● -n: 非GUI模式执行JMeter   ● -t: 执行测试文件所在的位置   ● -l: 指定生成测试结果的保存文件,.jtl文件格式   ● -e: 测试结束后,生成测试报告   ●

  • 我正试图利用Jenkins中的“发布JUnit测试结果报告”,但无法让它为我的android测试项目工作。我在Jenkins的android测试项目的设置基于以下指南:https://wiki.jenkins-ci.org/display/Jenkins/building+an+android+app+和+test+project 我希望有人能发布一个简单的逐步指南,说明如何从测试运行中获得JUn

  • 我的问题与这个问题非常相似,只是针对maven和java。 我正在测试grpc,想把它变成一个简单的helloworld。proto位于test/proto文件夹中。 但是,该文件不会生成java文件(与/src/main/proto中的proto文件不同)。 所以我的问题是如何在测试文件夹中为proto生成代码?

  • 问题内容: 我正在使用Ant手册中的Hello World with Ant教程来学习有关Ant的知识。 本教程的最后一部分涉及将JUnit测试添加到项目中。 我已经按照教程中的说明进行了所有工作,现在要进行一些小的更改。 我要进行的更改之一是在典型的构建过程中运行测试,但* Test.class文件最终不在该应用程序的最终.jar文件中。这是因为我将要从事的最终项目是针对硬盘空间有限且仅支持Ja

  • 我在我的Java,Spring Boot控制器中创建了一个函数,它允许我根据参数获得数据的和值,这很有效。然而,我很难理解用Junit和Mockito测试这个功能的最佳方式是什么?到目前为止,我已经创建了一个测试函数,它返回一个特定数组字段的值。如何能够返回。thenreturn()中的值,该值根据给定的serviceID求和?任何帮助或建议任何其他有用的帖子将被感谢,因为我无法找到任何相关的或我