Wiremock Stub'ı aramaya çalışırken bağlantı reddedildi

Aug 17 2020

Cucumber-JVM'yi WireMock ile entegre etmeye çalışıyorum ve

java.net.ConnectException: Connection refused: connect

Cucumber.io'daki Resmi Belgeler de dahil olmak üzere birkaç öğretici denedim ve ayrıca bunları da denedim:

Baeldung'dan WireMock'a Giriş

StackOverflow'dan öğeler

Wiremock Github Sorunları sayfası

Gradle bağımlılıklarım:

implementation 'org.springframework.boot:spring-boot-starter-web'   
testImplementation 'io.cucumber:cucumber-java:6.2.2'
testImplementation 'io.cucumber:cucumber-junit:6.2.2'
testImplementation 'io.rest-assured:spring-web-test-client:4.3.1'
testCompile "com.github.tomakehurst:wiremock-jre8:2.27.0"
compile group: 'io.cucumber', name: 'cucumber-spring', version: '6.4.0'

Temel fikir, bir Sunucu Yanıtıyla Alay Etmektir, bu nedenle gelecekte birkaç mikro hizmet arasında bazı entegrasyon testleri oluşturabileceğim. Fikir, The Cucumber for Java Book'u okurken bir kitaptan geldi Mikro hizmetleri test etmenin daha iyi yolları varsa, yeni fikirlere açığım.

Adım Tanımlarımın bulunduğu bir Test Sınıfım var ve bağlantı noktası bilgilerini bir özellik dosyası oluşturuyor. Aşağıdaki gibi:

@SpringBootTest
@CucumberContextConfiguration
public class ConnectionWithCucumber {

    @Value("${another.server.port}")
    private int PORT;

    @Rule
    private WireMockRule wireMockRule = new WireMockRule(PORT);

    private String messageResult;

    @Given("I want to read a message")
    public void iWantToRead() {
        createMessageStub();
    }

    @When("I send the request")
    public void iSendTheRequest() {
        messageResult = given().get("localhost:8082/message").getBody().asString();
    }

    @Then("I should be able to read the word {string}")
    public void iShouldBeAbleToReadTheWord(String arg0) {
        assertEquals(arg0, messageResult);
    }

    private void createMessageStub() {
        wireMockRule.stubFor(get(urlEqualTo("/message"))
                .withHeader("Accept", equalTo("application/json"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("message")));
    }
}

Ayrıca çalıştırılabilir bir örnek içeren bir depo oluşturdum .

Bir README dosyası bulamazsanız, depoya bakarken projeyi aşağıdakileri kullanarak çalıştırabilirsiniz:

./gradlew cucumber

veya Windows kullanıyorsanız:

gradle cucumber

Çalıştırdıktan sonra, kodu yeniden düzenledim ve yukarıda bağladığım depodaki örneği bıraktım, aynı problemi yaşıyorsanız kontrol edin.

Yanıtlar

2 M.P.Korstanje Aug 18 2020 at 02:17

WireMockRuleBağlıdır @RuleSalatalık kullanıldığında herhangi bir etkisi yoktur JUnit 4. gelmektedir açıklama. Bunun yerine @AutoConfigureWireMock, spring-boot-starter-webwiremock'u kurmak için from kullanmayı düşünün.

├── pom.xml
└── src
    ├── main
    │   └── java
    │       └── com
    │           └── example
    │               └── Application.java
    └── test
        ├── java
        │   └── com
        │       └── example
        │           └── CucumberTest.java
        └── resources
            ├── application.yml
            ├── com
            │   └── example
            │       └── hello.feature
            └── junit-platform.properties
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>com.example</artifactId>
    <version>1.0.0-SNAPSHOT</version>

    <properties>
        <java.version>11</java.version>
        <cucumber.version>6.5.0</cucumber.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-cloud.version>Hoxton.SR7</spring-cloud.version>
    </properties>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-contract-stub-runner</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-java</artifactId> <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-spring</artifactId>
            <version>${cucumber.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>io.cucumber</groupId> <artifactId>cucumber-junit-platform-engine</artifactId> <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>
package com.example;

import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
public class Application {

    @Configuration
    @ConfigurationProperties("com.example")
    public static class HelloConfiguration {

        String helloService;

        public String getHelloService() {
            return helloService;
        }

        public void setHelloService(String helloService) {
            this.helloService = helloService;
        }

    }

    @RestController
    public static class HelloController {

        private final RestTemplate helloService;

        public HelloController(
                RestTemplateBuilder restTemplateBuilder,
                HelloConfiguration configuration) {
            this.helloService = restTemplateBuilder
                    .rootUri(configuration.getHelloService())
                    .build();
        }

        @RequestMapping("/local")
        public String local() {
            return "Greetings from Local!";
        }

        @RequestMapping("/remote")
        public String remote() {
            return helloService.getForObject("/", String.class);
        }

    }

}
package com.example;

import com.github.tomakehurst.wiremock.client.WireMock;
import io.cucumber.java.en.Given;
import io.cucumber.junit.platform.engine.Cucumber;
import io.cucumber.spring.CucumberContextConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.cloud.contract.wiremock.AutoConfigureWireMock;
import org.springframework.test.web.servlet.MockMvc;

import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@Cucumber
@CucumberContextConfiguration
@SpringBootTest
@AutoConfigureMockMvc
@AutoConfigureWireMock(port = 0)
public class CucumberTest {

    @Autowired
    private MockMvc mvc;

    @Given("the application says hello")
    public void getLocalHello() throws Exception {
        mvc.perform(get("/local").accept(APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Greetings from Local!")));
    }

    @Given("the stub says hello")
    public void getRemoteHello() throws Exception {
        stubFor(WireMock.get("/").willReturn(okJson("Greetings from Stub!")));

        mvc.perform(get("/remote").accept(APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Greetings from Stub!")));
    }

}
Feature: Hello world

  Scenario: Calling a rest end point
    * the application says hello
    * the stub says hello
com:
  example:
    hello-service: http://localhost:${wiremock.server.port}
3 ManojRamanan Aug 17 2020 at 14:28

java.net.ConnectException: Bağlantı reddedildi: bu bağlantı, bağlantı noktasında dinleyen hizmet olmadığı anlamına gelir, lütfen hizmetin çalıştığı bağlantı noktasını yazdırmayı deneyin ve kontrol edin. Wiremock'un çalışıp çalışmadığını kontrol ettiğinizi görebiliyorum, lütfen portu da kontrol edin

Bunun gibi test özelliği ekleyebilirsiniz. bu, varsayılan application.properties öğesini geçersiz kılar

    @TestPropertySource(properties = {
        "application.location=http://localhost:8082/app/api/v1/"

})

lütfen satırdaki url'yi şu şekilde değiştirin:

 Header header = new Header("Accept","application/json")
 messageResult = given().header(header).port(8082).get("/message").getBody().asString();

onun yerine

  messageResult = given().get("localhost:8082/message").getBody().asString();

benim için çalışıyor

@SpringBootTest
@CucumberContextConfiguration
public class ConnectionWithCucumber {

    @Value("${another.server.port}") private int PORT; @Rule private WireMockRule wireMockRule = new WireMockRule(8082); private WireMockServer wireMockServer = new WireMockServer(8083); private String messageResult; @Value("${test.word}")
    private String word;

    @Value("${test.number}")
    private String number;

    @Test
    public void testWord(){
        wireMockServer.start();
        wireMockRule.start();
        wireMockRule.isRunning();
        wireMockServer.isRunning();
        System.out.println(wireMockRule.port());
        assertThat(word).isEqualTo("word");
        assertThat(number).isEqualTo("number");
    }


    @Given("I want to read a message")
    public void iWantToRead() {
        wireMockServer.start();
        wireMockRule.start();
        wireMockRule.isRunning();
        wireMockServer.isRunning();
        System.out.println("wireMockRule port " + wireMockRule.port());
        System.out.println("wireMockServer port " + wireMockServer.port());

        // Start the stub
        createMessageStubServer();
        createMessageStub();

        wireMockServer.getStubMappings();
        wireMockRule.getStubMappings();
    }

    @When("I send the request")
    public void iSendTheRequest() {
        System.out.println("iSendTheRequest" + wireMockRule.isRunning());
        System.out.println("iSendTheRequest" + wireMockServer.isRunning());
        Header header = new Header("Content-Type","application/json");
        messageResult = given().port(8082).and().header("Accept","application/json").and()
                .get("/message").getBody().asString();

        System.out.println(messageResult);

    }

    @Then("I should be able to read the word {string}")
    public void iShouldBeAbleToReadTheWord(String arg0) {
        System.out.println(messageResult);
        System.out.println("arg0"+arg0);
        assertEquals(arg0, messageResult);
    }

    private void createMessageStub() {
        wireMockRule.stubFor(get(urlEqualTo("/message"))
                .withHeader("Accept", equalTo("application/json"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("Response")));
    }

    private void createMessageStubServer() {
        wireMockServer.stubFor(get(urlEqualTo("/message"))
                .withHeader("Accept", equalTo("application/json"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody("{\"message\":\"1\"}")));
    }
}

Bu, kullandığınız tel alay kuralı ve tel alay sunucusunu kullandığınız çalışma kodudur, her ikisini de dokümantasyona göre kullanmanıza gerek yoktur, tek başına wiremock kuralını kullanabilirsiniz, bu yeterlidir, her testten önce sunucuyu başlatır ve durdurur

lütfen bakın http://wiremock.org/docs/getting-started/

Bu test durumları diğer ortamlarda başarısız olabileceğinden rastgele bağlantı noktası kullanmayın, kodunuzda yaptığınız gibi sabit bağlantı noktasını kullanın

Ya wiremock kuralını ya da @AutoConfigureWireMock'u kullanmanın spring yolunu kullanabilirsiniz, bu bağımlılıkları otomatik olarak enjekte eder, böylece spring, junit yerine sahte sunucuyu başlatır ve durdurur.

lütfen bakın https://cloud.spring.io/spring-cloud-contract/reference/html/project-features.html#features-wiremock yay teli sahte belgeleri için

Burada dikkat edilmesi gereken bir şey daha var @ Kural ilkbahardan önce yürütülür, bu nedenle @ Kural junit'e ait olduğu için bağlantı noktası değerini almıyor, yalnızca @ Kural açıklamasında bağlantı noktasını sabit kodlamanız gerekir veya @AutoConfigureWireMock'u kullanabilirsiniz. kodlanmış