在为具有完全相同请求的多个响应设置MockServerClient时,我遇到了问题。
我用“时代”的期待来阅读这篇文章,但我无法让它与我的场景相适应。
如果使用此JSON调用服务(两次):
{
"id": 1
}第一个响应应该是“传递真”,第二个应该是“传递假”。
回应1:
{
"passed":true
}回应2:
{
"passed":false
}我设置了第一个请求,但是如何设置第二个请求?
import com.nice.project.MyService;
import com.nice.project.MyPojo;
import org.mockito.Mock;
import org.mockserver.integration.ClientAndServer;
import org.mockserver.matchers.TimeToLive;
import org.mockserver.matchers.Times;
import org.mockserver.model.Header;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.TestPropertySource;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.Mockito.when;
import static org.mockserver.integration.ClientAndServer.startClientAndServer;
import static org.mockserver.model.HttpRequest.request;
import static org.mockserver.model.HttpResponse.response;
@SpringBootTest
public class Tests{
private static final int PORT = 9998;
private static ClientAndServer mockServer;
@Autowired
private MyService myService;
@BeforeAll
public void init(){
mockServer = startClientAndServer(PORT);
mockServer
.when(
request()
.withPath(testUrlValidateTransactionOk).withMethod(HttpMethod.POST.name())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
)
.withBody(contains("\"id\":\"1\""))
).respond(
response().withStatusCode(HttpStatus.OK.value())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
)
.withBody("{\"passed\":true}"));
// What do i set here? Or in the snippet before by chaining?
// mockServer.when()...
}
@Test
void t1{
//myService will internally call the MockServer
//FIRST CALL -> Pass
MyPojo p = myService.call(1);
assertThat(p.isPassed()).isEqualTo(Boolean.TRUE);
//SECOND CALL -> No Pass
MyPojo p2 = myService.call(1);
assertThat(p2.isPassed()).isEqualTo(Boolean.FALSE);
}
}依赖性(相关):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://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.4.4</version>
</parent>
<groupId>com.nice.project</groupId>
<artifactId>testing</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>test</name>
<description>Testing</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<httpclient.version>4.5.13</httpclient.version>
<mock-server.version>5.11.2</mock-server.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--HTTP CLIENT-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!--TEST-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-netty</artifactId>
<version>${mock-server.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mock-server</groupId>
<artifactId>mockserver-client-java</artifactId>
<version>${mock-server.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>提前谢谢你。
发布于 2021-05-03 08:04:33
在跟踪和深入文档和测试之后。
我发现,您可以指定一个"Times“,它将与期望匹配,从而完美地解决了我的问题。
链接:https://www.mock-server.com/mock_server/creating_expectations.html
对于我使用"Times.exactly(1)".的每一个期望
这样做的方式是将期望添加到列表中,当它匹配时,它将被消费、并从列表中删除,留下以下内容。
如果没有找到对调用的期望,它将从模拟服务器返回一个404。
正确代码:
//The first call will land here, and then this expectation will be deleted, remaining the next one
mockServer
.when(
request()
.withPath(testUrlValidateTransactionOk).withMethod(HttpMethod.POST.name())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
)
.withBody(
json("{\"id\":1}",
MatchType.ONLY_MATCHING_FIELDS)),
Times.exactly(1)
).respond(
response().withStatusCode(HttpStatus.OK.value())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
)
.withBody("{\"passed\":true}"));
//After the first call this will be consumed and removed, leaving no expectations
mockServer
.when(
request()
.withPath(testUrlValidateTransactionOk).withMethod(HttpMethod.POST.name())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
)
.withBody(
json("{\"id\":1}",
MatchType.ONLY_MATCHING_FIELDS)),
Times.exactly(1)
).respond(
response().withStatusCode(HttpStatus.OK.value())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString())
)
.withBody("{\"passed\":false}"));发布于 2021-04-16 00:49:04
您可以通过在方法中包装时间/请求/响应行为并多次调用它来创建响应序列,如下所示:
private void whenValidateTransactionReturn(boolean isPassed) {
mockServer
.when(
request()
.withPath(testUrlValidateTransactionOk)
.withMethod(HttpMethod.POST.name())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString()))
.withBody(contains("\"id\":\"1\"")))
.respond(
response()
.withStatusCode(HttpStatus.OK.value())
.withHeaders(
new Header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString()))
.withBody("{\"passed\":" + isPassed + "}"));
}然后您可以多次调用此方法:
@Test
void testValidationFailsSecondTime() {
whenValidateTransactionReturn(true);
whenValidateTransactionReturn(false);
//
// Test logic
//
// mockServer.verify(...);
}https://stackoverflow.com/questions/67091263
复制相似问题