簡體   English   中英

使用 java junit5 maven spring-boot 從提供者端驗證 PACT 時遇到問題

[英]Having trouble in verifying the PACT from provider side using java junit5 maven spring-boot

我必須在java + spring-boot + maven中進行PACT驗證。 我目前正在使用 junit5 運行此測試。

我的 pom.xml 看起來像

        <dependency>
            <groupId>au.com.dius</groupId>
            <artifactId>pact-jvm-provider-junit5</artifactId>
            <version>4.0.10</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.google.code.gson</groupId>
                    <artifactId>gson</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>au.com.dius</groupId>
            <artifactId>pact-jvm-consumer-junit5</artifactId>
            <version>4.0.10</version>
        </dependency>
        <plugin>
                <groupId>au.com.dius.pact.provider</groupId>
                <artifactId>maven</artifactId>
                <version>4.1.11</version>
                <configuration>
                    <pactDirectory>${basedir}/target/pacts</pactDirectory>
                    <pactBrokerUrl><BROKERURL></pactBrokerUrl>
                    <projectVersion><PROJECTVERSION></projectVersion>
                    <trimSnapshot>true</trimSnapshot>
                </configuration>
            </plugin>

消費者端代碼運行完美並發布在協議代理上,這是它的片段。

package com.contract;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.StringEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.testng.Assert;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

import au.com.dius.pact.consumer.MockServer;
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
import au.com.dius.pact.consumer.junit5.PactTestFor;
import au.com.dius.pact.core.model.RequestResponsePact;
import au.com.dius.pact.core.model.annotations.Pact;


@ExtendWith(PactConsumerTestExt.class)

class ContractTest {

    public static final String jwt_token = "Bearer eyJraWQiOiIyZjFiNzlmMS0xMDQ2LTQ2NGYtYjM5YS0xOGY4MDg5ZGMyMzIiLCJ0eXAiOiJhdCtqd3QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJodHRwczovL3RlbmFudDE1LWFkZW1hdHJpeHN0YWNrNC10cmlhbC5kc21sYWIuYm1jLmNvbSIsImNsaWVudF9pZCI6IjVmNDU4ZjBlLWZmMzAtNDQ2ZC04ZTQwLWYzNjBlNjgyZjYyNSIsInRlbmFudCI6InN0YWNrNHRlbmFudDYiLCJqdGkiOiI4NDc3MDBhNC1hYWY0LTQ2NWMtYmNhYi05MDM0MzYxOTY0MDIiLCJzdWIiOiJEZW1vIiwiaXNzIjoiaHR0cHM6Ly9hZGVpdHNtMi1yc3NvLmRzbWxhYi5ibWMuY29tL3Jzc28iLCJpYXQiOjE2MjY3Njg0MjQsImV4cCI6MTYyNjc2OTMyNH0.EoXpqiyo5nvdPeYHfqq0sa15dQKYayD60UEboPVJojuYBKmvvj2yU03e61wy9Fkq2pZdoTNTifAeLDiG0dYKdlYOI5YTx_K6HGMav6ofYeOwIUj4OBVu7NyWxXVQz-3aXoIyu-MifUtvs6oQwf2YZmOEVtbPuCBxa9C9yA4i72g1TD31Rba1-e5cGG5ipiIE7UaunJ2K-mkt-BL2kzmu6OHdIP6vly7iTzxfOccdrjXEmedgX2hpnPcL_2os5wHCLwdHJwuYLPlgqDbSLHgpXdGL43Jg4ASBbFHg3h30y1yXYJazlgOwvVeBoOVcQYnXBh7wHTMik7zVMAo1VL8N_Q";
    
    public static final String API_V1_VIEW_ALGORITHM = "/aif/api/v1.0/algorithm/b82d4617-c39f-448b-bdf8-3fd52e3250ba";
    
    public static final String BODY_GET_VIEW_ALGO_V1 = "{\"tenantId\":\"6881408\",\"id\":\"5bc098db-7acb-4361-86a9-3c439b477142\",\"name\":\"New Job\",\"description\":\"New Job\",\"creationTime\":\"1625054173273\",\"template\":\"\",\"modifiedTime\":\"1625054173273\",\"owner\":\"ppan\",\"enable\":\"true\",\"executionMode\":\"onDemand\",\"definition\":\"\"}";
    
    private final static Map<String, String> headers;
    static {
        headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("Authorization", jwt_token);
        headers.put("authtype", "rsso-jwt");
    }

    @BeforeEach
    public void setUp(MockServer mockServer) {
        assertThat(mockServer, is(notNullValue()));
    }
    
    /* ----------------------------------Pact methods ----------------------------------------------------*/

    @Pact(provider = <provider name> , consumer = <consumer name>)
    public RequestResponsePact createPactViewAlgoV1(PactDslWithProvider builder) {

        return builder
                .given("algorithm id")
                .uponReceiving("a request with details of Algorithm")
                .path(API_V1_VIEW_ALGORITHM)
                    .method("GET")
                    .headers(headers)
                .willRespondWith()
                    .status(200)
                    .body(BODY_GET_VIEW_ALGO_V1)
                .toPact();
    }
    
    
    /* ----------------------------------Test methods ----------------------------------------------------*/
    
    @Test
    @PactTestFor(pactMethod = "createPactViewAlgoV1")
    public void testTokenRequest(MockServer mockServer) throws ClientProtocolException, IOException {
        HttpResponse httpResponse = Request.Get(mockServer.getUrl() + API_V1_VIEW_ALGORITHM)
                .addHeader("Content-Type", headers.get("Content-Type"))
                .addHeader("Authorization",headers.get("Authorization"))
                .addHeader("authtype", headers.get("authtype"))
                .execute()
                .returnResponse();
        assertEquals(httpResponse.getStatusLine().getStatusCode(), 200);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
        AIFAlgorithmModelNew actualResult = objectMapper.readValue(httpResponse.getEntity().getContent(), AIFAlgorithmModelNew.class);
        assertEquals(actualResult.getTenantId().toString(), "6881408");
        assertEquals(actualResult.getExecutionMode().toString(), "onDemand");
        assertEquals(actualResult.getEnable().toString(), "true");
        assertEquals(actualResult.getName().toString(), "New Job");
    }
}

我已經用標准的 Pact 格式編寫了我的 Pact 提供程序測試類。 我目前正在嘗試在端口 8091 上運行它。也嘗試使用端口 9362。 看起來像這樣

package com.aif.api.contract;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;

<Code libraries>

import au.com.dius.pact.provider.junit.Provider;
import au.com.dius.pact.provider.junit.State;
import au.com.dius.pact.provider.junit.loader.PactBroker;
import au.com.dius.pact.provider.junit5.HttpTestTarget;
import au.com.dius.pact.provider.junit5.HttpsTestTarget;
import au.com.dius.pact.provider.junit5.PactVerificationContext;
import au.com.dius.pact.provider.junit5.PactVerificationInvocationContextProvider;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.restassured.RestAssured;
import io.restassured.http.Cookie;
import io.restassured.config.SSLConfig;

import static org.mockito.Mockito.when;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Base64;
import java.util.UUID;

import javax.ws.rs.core.Response;

import org.apache.http.HttpRequest;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.TestTemplate;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;

@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = main.class)
@AutoConfigureMockMvc
@TestPropertySource(locations = "classpath:application-contract-test.properties")
@Provider("Provider")
@PactBroker(
        host="${PACTBROKER_HOST:PACTBroker URL}",
        port="${PACTBROKER_PORT:9292}"
        )
public class BasicTest {
    
    static {
        System.setProperty("javax.net.ssl.keyStore", "./conf/server_key.p12");
        System.setProperty("javax.net.ssl.keyStorePassword", "Y2hhbmdlaXQ=");
        }
    
    @Autowired
    private ApplicationContext context;
    
    @MockBean
    Algor
    
    @MockBean
    AlgorithmResource algorithmResource;
    
    @Value("${server.port}")
    private int serverPort;
    
    @Value("${pact.provider.version}")
    private String version;
    
    @Value("${pact.verifier.publishResults}")
    private String publishResults;
    
    @BeforeEach
    void setupTestTarget(PactVerificationContext context) {
        System.out.println("Inside setupTestTarget");
        MockitoAnnotations.initMocks(this);
        context.setTarget(new HttpTestTarget("localhost", serverPort, "/"));
        System.setProperty("pact.provider.version", version);
        System.setProperty("pact.verifier.publishResults", publishResults);   
    }
    
    @TestTemplate
      @ExtendWith(PactVerificationInvocationContextProvider.class)
      void pactVerificationTestTemplate(PactVerificationContext context, HttpRequest request) {
        context.verifyInteraction();
      }
    
    /* consumer = <Consumer Name> */
    @State("algorithm id")
    public void getAlgorithmById() throws Exception {
        System.out.println("Inside getAlgorithmById");
        AlgorithmResponseTOFull responseTO = new AlgorithmResponseTOFull();
        responseTO.setTenantId("6881408");
        responseTO.setId("5bc098db-7acb-4361-86a9-3c439b477142");
        responseTO.setName("New Job");
        responseTO.setDefinition("");
        responseTO.setDescription("New Job");
        responseTO.setCreationTime("1625054173273");
        responseTO.setModifiedTime("1625054173273");
        responseTO.setOwner("ppans");
        responseTO.setEnable("true");
        responseTO.setExecutionMode("onDemand");
        responseTO.setTemplate(getAlgorithmTemplateResponseTO());
        
        Response response = Response.ok(Util.buildResponse(responseTO, Constant.STATUS_MSG_SUCCESS)).build();
        
        when(algorithmResource.getById(Mockito.any())).thenReturn(response);
    }
}

當我運行這個時,我收到類似的錯誤

Verifying a pact between <consumer name> and <provider name>
  [Using Pact Broker PACTBROKERURL:9292]
  Given algorithm id
  a request with details of Algorithm
Inside pactVerificationTestTemplate
    returns a response which
      has status code 200 (FAILED)
      has a matching body (FAILED)

Failures:

0) Verifying a pact between <consumer name> and <provider name> - a request with details of Algorithm returns a response which has statusResult code 200
      expected status of 200 but was 401

1) Verifying a pact between <consumer name> and <provider name> - a request with details of Algorithm returns a response which has a matching body
      Expected a response type of 'application/json' but the actual type was 'text/html'

請幫我解決這個問題,因為我遇到了上面的錯誤並且無法解決它

在編寫測試的使用者中,期望響應為 200,響應類型為“application/json”。 如果可能,請分享您編寫的消費者測試。 請檢查在契約代理 url 上生成的契約,以及它期望的響應和響應類型是什么。

401 表示請求包含無效憑據或沒有憑據。

鑒於您的消費者測試中包含 JWT,我猜測它在提供者測試運行時已過期。

請參閱https://docs.pact.io/provider/handling_auth/了解處理此問題的策略以及此處的研討會以了解如何將其付諸行動: https : //docs.pact.io/implementation_guides/workshops/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM