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

Spring Cloud Contract+Pact(Broker):json字符串不能为空或为空

蓬长恨
2023-03-14

我一直在尝试使用Spring Cloud Contract(SCC)进行合同测试,现在尝试将Pact与SCC结合使用,作为使用纯Pact之前的中间步骤。

在我的消费者项目中,我指定了一个简单的合同:

@RunWith(SpringRunner.class)
@SpringBootTest
public class AccountServicePactTest {
    @Autowired
    TransactionService transactionService;

    @Rule
    public PactProviderRuleMk2 mockProvider = new PactProviderRuleMk2("account-service", "localhost", 8081, this);

    @Pact(consumer = "transaction-service")
    public RequestResponsePact createPact(PactDslWithProvider builder) {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json;charset=UTF-8");

        return builder
                .given("An account with UUID 8ea0f76b-b7a6-49eb-b25c-073b664d2de3 exists")
                .uponReceiving("Request for an account by UUID")
                .path("/api/accounts/8ea0f76b-b7a6-49eb-b25c-073b664d2de3")
                .method("GET")
                .willRespondWith()
                .headers(headers)
                .status(200)
                .body("{\n" +
                        " \"accountUUID\": \"8ea0f76b-b7a6-49eb-b25c-073b664d2de3\",\n" +
                        " \"customerId\": 1,\n" +
                        " \"balance\": 0.00,\n" +
                        "}")
                .toPact();
    }

    @Test
    @PactVerification
    public void runTest() {
        AccountRetrievalRequest request = new AccountRetrievalRequest(UUID.fromString("8ea0f76b-b7a6-49eb-b25c-073b664d2de3"));
        AccountDTO accountDTO = transactionService.retrieveAccount(request);
        assertThat(accountDTO.getAccountUUID()).isEqualTo(UUID.fromString("8ea0f76b-b7a6-49eb-b25c-073b664d2de3"));
    }

}
    <plugin>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-provider-maven_2.12</artifactId>
        <version>3.5.22</version>
        <configuration>
            <pactBrokerUrl>http://localhost:8888</pactBrokerUrl>
            <pactBrokerUsername></pactBrokerUsername>
            <pactBrokerPassword></pactBrokerPassword>
            <trimSnapshot>true</trimSnapshot>
        </configuration>
        <executions>
            <execution>
                <phase>install</phase>
                <goals>
                    <goal>publish</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-contract-maven-plugin</artifactId>
        <version>${spring-cloud-contract.version}</version>
        <extensions>true</extensions>
        <configuration>
            <contractsRepositoryUrl>pact://http://localhost:8888</contractsRepositoryUrl>
            <contractDependency>
                <groupId>${project.groupId}</groupId>
                <artifactId>${project.artifactId}</artifactId>
                <version>+</version>
            </contractDependency>
            <contractsMode>REMOTE</contractsMode>
            <packageWithBaseClasses>com.abnamro.internship.bank.accountservice.pacts</packageWithBaseClasses>
        </configuration>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-contract-pact</artifactId>
                <version>${spring-cloud-contract.version}</version>
            </dependency>
        </dependencies>
    </plugin>

    <plugin>
        <groupId>au.com.dius</groupId>
        <artifactId>pact-jvm-provider-maven_2.12</artifactId>
        <version>3.5.11</version>
        <configuration>
            <serviceProviders>
                <serviceProvider>
                    <name>account-service</name>
                    <pactBrokerUrl>http://localhost:8888/</pactBrokerUrl>
                </serviceProvider>
            </serviceProviders>
        </configuration>
    </plugin>

SCC验证程序所需的基类:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AccountServiceApplication.class)
public abstract class Account_serviceContractsBase {
    @Autowired
    private WebApplicationContext webApplicationContext;
    @Autowired
    private AccountRepository accountRepository;

    @Before
    public void setup() {
        Account account = new Account(UUID.fromString("8ea0f76b-b7a6-49eb-b25c-073b664d2de3"), Integer.toUnsignedLong(1),
                0.00d);
        accountRepository.save(account);
        RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
        System.out.println(account.getAccountUUID());
    }

    @After
    public void teardown() {}
}

SCC生成的测试:

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ContractsTest extends Account_serviceContractsBase {

    @Test
    public void validate_0_account_service_pact() throws Exception {
        // given:
            MockMvcRequestSpecification request = given();

        // when:
            ResponseOptions response = given().spec(request)
                    .get("/api/accounts/8ea0f76b-b7a6-49eb-b25c-073b664d2de3");

        // then:
            assertThat(response.statusCode()).isEqualTo(200);
            assertThat(response.header("Content-Type")).isEqualTo("application/json;charset=UTF-8");
        // and:
            DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
            assertThatJson(parsedJson).field("['accountUUID']").isEqualTo("8ea0f76b-b7a6-49eb-b25c-073b664d2de3");
            assertThatJson(parsedJson).field("['customerId']").isEqualTo(1);
            assertThatJson(parsedJson).field("['balance']").isEqualTo(0.0);
    }

}

运行测试会出现以下异常:

java.lang.IllegalArgumentException: json string can not be null or empty
@RestController
@RequestMapping("/api")
public class AccountController {
...
    @GetMapping("/accounts/{accountUUID}")
    public ResponseEntity<Account> retrieveAccount(@PathVariable("accountUUID") UUID accountUUID) {
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE);

        return new ResponseEntity<>(accountService.retrieveAccount(accountUUID),
                httpHeaders, HttpStatus.OK);
    }

共有1个答案

司浩壤
2023-03-14

原来我的基类设置不正确。工作基类,它只是模拟被调用的服务方法并返回一个测试帐户:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = AccountServiceApplication.class)
public abstract class Account_serviceContractsBase {

    @Autowired
    private WebApplicationContext webApplicationContext;

    @MockBean
    private AccountService accountService;

    @Before
    public void setup() {
        Account account = new Account();
        account.setAccountUUID(UUID.fromString("8ea0f76b-b7a6-49eb-b25c-073b664d2de3"));
        account.setCustomerId(1L);
        account.setBalance(0.00d);
        when(accountService.retrieveAccount(UUID.fromString("8ea0f76b-b7a6-49eb-b25c-073b664d2de3"))).thenReturn(account);
        RestAssuredMockMvc.webAppContextSetup(webApplicationContext);
    }

    @After
    public void teardown() {}
}
 类似资料:
  • 在下面的代码中,我需要检查版本字符串是否为空,然后将其值附加到请求变量。 如何检查不在if条件下?

  • 问题内容: 由于空字符串是Go的零/默认值,因此我决定将所有此类字段定义为。例如 如果该值不适用于该特定字段,则我正在发送数据的应用程序期望使用null而不是空字符串。 这是正确的方法吗?或者有人可以向我指出比这更好的方法。 问题答案: 在json包文档中: 指针值编码为指向的值。nil指针编码为空JSON对象。 因此,您可以存储指向字符串的指针,如果不为nil,则将其编码为字符串;如果为nil,

  • 问题内容: 我是Java新手。无法检查null。你能启发我吗?我有没有元素的字符串数组。 我尝试了这段代码 问题答案: 非常精确 会检查不是。并且将不为空[你也可以放弃该空格检查长度之前修剪。

  • 问题内容: 我敢肯定,以前必须以不同的方式询问过这个问题- 因为isEmptyOrNull很常见,但人们以不同的方式实现它。但是我在最好的可用方法方面有以下好奇的查询,这对内存和性能都有好处。 1)下方不考虑所有空格,例如在XML标签为空的情况下 2)低于一保重但修剪会降低性能和记忆力 3)将两者结合可以节省一些性能和内存(克里斯在评论中建议) 4)转换为模式匹配器(仅在字符串长度不为零时调用)

  • 问题内容: 如何检查字符串是否不为null也不为空? 问题答案: 那呢? 确保&&按此顺序使用的部分,因为如果的第一部分&&失败,java将不会继续评估第二部分,因此确保你不会从为null的情况下得到null指针异常。 请注意,仅从Java SE 1.6起可用。你必须检查以前的版本。 也要忽略空格: (由于可以简化为也可以测试其他空白) 包裹在一个方便的功能中: 成为:

  • 问题内容: 我在Stream中有Google Guava: 如您所见,过滤器函数内部有一条语句。 我不想在项目中再使用番石榴,所以我只想替换为: 我怎样才能使它更优雅? 问题答案: 您可以编写自己的谓词: 然后,将其用作您的过滤器参数。