वायरमॉक स्टब को कॉल करने की कोशिश करने पर कनेक्शन ने इनकार कर दिया
मैं खीरे-जेवीएम को वायरमॉक के साथ एकीकृत करने की कोशिश कर रहा हूं और मुझे मिल रहा है
java.net.ConnectException: Connection refused: connect
मैंने कई ट्यूटोरियल की कोशिश की है, जिसमें ककड़ी से सरकारी डॉक्स शामिल हैं ।
बेल्डुंग से वायरमॉक का परिचय
StackOverflow से सामान
वायरमॉक जीथब इश्यूज पेज
मेरी स्नातक निर्भरताएँ:
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'
मूल विचार एक सर्वर रिस्पांस को मॉक करने के लिए है, इसलिए भविष्य में मैं कई माइक्रोसर्विस के बीच कुछ एकीकरण परीक्षण बना पाऊंगा। जब मैं जावा बुक के लिए ककड़ी पढ़ रहा हूं, तो यह विचार एक किताब से आया था कि अगर मैं नए विचारों के लिए खुला हूं तो माइक्रोसेवा का परीक्षण करने के बेहतर तरीके हैं।
मैंने अपनी स्टेप परिभाषाओं के साथ एक टेस्ट क्लास ली है जो पोर्ट इंफॉर्मेशन को प्रॉपर फाइल बनाता है। नीचे की तरह:
@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")));
}
}
और मैंने एक रन करने योग्य उदाहरण के साथ एक रिपॉजिटरी भी बनाई है ।
यदि आपको README फाइल नहीं मिलती है, तो रेपो को देखते हुए आप प्रोजेक्ट को चलाकर उपयोग कर सकते हैं:
./gradlew cucumber
या यदि आप विंडोज पर हैं:
gradle cucumber
जब मैं इसे काम कर रहा था, तब मैंने कोड को फिर से सक्रिय कर दिया था और उदाहरण के लिए मैंने ऊपर लिंक की गई रिपॉजिटरी पर छोड़ दिया था, यदि आपके पास एक ही समस्या है तो इसे देखें।
जवाब
WireMockRule
पर निर्भर करता है @Rule
एनोटेशन जो JUnit 4. से आता है यह जब ककड़ी में इस्तेमाल किया कोई असर नहीं होता है। इसके बजाय सेटअप वायरमॉक @AutoConfigureWireMock
से उपयोग spring-boot-starter-web
करने पर विचार करें ।
├── 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}
java.net.ConnectException: कनेक्शन ने इनकार कर दिया: इसका मतलब है कि पोर्ट पर कोई सेवा नहीं है, कृपया उस पोर्ट को प्रिंट करने का प्रयास करें जिसमें सेवा चल रही है और जांचें। मैं देख सकता हूँ कि यू पहले ही जाँच कर चुके हैं कि वायरमॉक चल रहा है या नहीं, कृपया पोर्ट की भी जाँच करें
आप इस तरह से परीक्षण संपत्ति जोड़ सकते हैं। वह डिफ़ॉल्ट एप्लिकेशन को ओवरराइड करेगा
@TestPropertySource(properties = {
"application.location=http://localhost:8082/app/api/v1/"
})
कृपया url को लाइन में बदलें
Header header = new Header("Accept","application/json")
messageResult = given().header(header).port(8082).get("/message").getBody().asString();
की बजाय
messageResult = given().get("localhost:8082/message").getBody().asString();
यह मेरे लिए काम कर रहा है
@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\"}")));
}
}
यह वह कार्य कोड है जो आप वायर मॉक नियम और वायर मॉक सर्वर का उपयोग कर रहे हैं, हमें डॉक्यूमेंटेशन के अनुसार दोनों का उपयोग करने की आवश्यकता नहीं है, आप अकेले वायरमॉक नियम का उपयोग कर सकते हैं, जो कि प्रत्येक परीक्षण से पहले सर्वर को शुरू और बंद कर देगा।
कृपया संदर्भ देखें http://wiremock.org/docs/getting-started/
यादृच्छिक परीक्षण का उपयोग न करें क्योंकि इस परीक्षण के मामले अन्य वातावरण में विफल हो सकते हैं क्योंकि आप अपने कोड के साथ निर्धारित पोर्ट का उपयोग करते हैं
आप या तो वायरमॉक नियम का उपयोग कर सकते हैं या @AutoConfigureWireMock का उपयोग करने के स्प्रिंग तरीके से ऑटो पर निर्भरता को इंजेक्ट करेगा ताकि वसंत शुरू हो जाएगा और जूनट के बजाय मॉक सर्वर को बंद कर दिया जाएगा।
कृपया संदर्भ देखें https://cloud.spring.io/spring-cloud-contract/reference/html/project-features.html#features-wiremock वसंत तार नकली डॉक्स के लिए
यहाँ एक और बात ध्यान देने वाली है @Rule को स्प्रिंग से पहले निष्पादित किया जाता है, इसलिए इसे पोर्ट वैल्यू नहीं मिल रहा है क्योंकि @Rule junit के अंतर्गत आता है, आपको @Rule एनोटेशन में केवल पोर्ट को हार्ड कोड करना होता है या आप @AutoConfearWireMock का उपयोग कर सकते हैं, यही कारण है कि मेरे पास है इसे हार्डकोड किया गया