Spring Cloud Contract + Pact (брокер): строка json не может быть пустой или пустой - PullRequest
0 голосов
/ 16 ноября 2018

Я экспериментировал с Контрактным тестированием с использованием 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"));
    }

}

(я знаю, что жесткое кодирование UUID, customerId и balance делает тест хрупким, но это всего лишь простой тест)

Использование пактаПлагин -jvm-provider-maven_2.12 (плагин провайдера на стороне потребителя, сбивающий с толку, я знаю) файл Pact передается в Pact Broker:

    <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>

Пока все хорошо.

На проекте провайдера я сталкиваюсь с проблемами, пытающимися проверить контракт.Опять же, я использую SCC и Pact вместе.Фрагмент плагина pom.xml:

    <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

Я не могу понять, почему строка является пустой или нулевой.Запуск приложения и использование Postman для проверки конечной точки работает просто отлично.

Это часть контроллера:

@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);
    }

Я что-то упустил, но не могу найти что.Мысли?

РЕДАКТИРОВАТЬ: (сгенерированный) тест пройден только при использовании SCC.

1 Ответ

0 голосов
/ 19 ноября 2018

Оказалось, что мой Базовый класс не был настроен должным образом.Рабочий базовый класс, который просто проверяет вызываемый метод службы и возвращает тестовую учетную запись:

@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() {}
}
...