我有一个使用Feign客户端的课程.之前我使用过Mockito并为Feign客户端中的每个方法调用提供了存储响应.现在我想使用WireMock,以便我可以看到我的代码正确处理不同类型的响应代码.我该怎么做呢?我无法弄清楚如何在测试中连接我的Feign客户端,并将其连接起来,以便它使用Wiremock而不是我在我的application.yml文件中设置的URL .任何指针都将非常感激.
我有一个Spring Boot测试,它使用wiremock来模拟外部服务.为了避免与并行构建冲突,我不想为wiremock设置固定端口号,并且希望依赖其动态端口配置.
该应用程序使用application.yml中external.baseUrl设置的property()(在src/test/resources下).但是我找不到以编程方式覆盖它的方法.我尝试过这样的事情:
WireMockServer wireMockServer = new WireMockServer();
wireMockServer.start();
WireMock mockClient = new WireMock("localhost", wireMockServer.port());
System.setProperty("external.baseUrl", "http://localhost:" + wireMockServer.port());
Run Code Online (Sandbox Code Playgroud)
但它不起作用,而是使用application.yml中的值.我看过的所有其他解决方案都使用静态值覆盖属性(例如在某些注释中),但在运行测试之前我不知道wiremock端口的值.
澄清:
弹簧引导和线缆都在随机端口上运行.那很好,我知道如何获得两个端口的价值.然而,wiremock应该模拟外部服务,我需要告诉我的应用程序如何到达它.我和这家external.baseUrl酒店一起做.我想在测试中设置的值当然取决于线程端口号.我的问题是如何在Spring启动测试中以编程方式设置属性.
我正在尝试使用独立的wiremock 创建一个API 模拟。响应正文取决于请求正文中的属性。
有了 JSON,我就能做到。这是示例映射:
{
"request":{
"method":"POST",
"bodyPatterns":[
{
"matchesJsonPath":"$.somekey.subkey[?(@.attribute == 'VALUE_123')]"
}
]
},
"response":{
"status":200,
"bodyFileName":"res.dat",
"headers":{
"Content-Type":"application/x-proto;charset=UTF-8"
}
}
}
Run Code Online (Sandbox Code Playgroud)
然而,我的主要要求是处理 google protobuf,我尝试使用文本格式代替它,嘲笑者将用它来模拟 API 进行响应。因此,请求文件是文本格式,并且没有任何 JSON 验证,例如双引号或每行末尾的逗号等。
我发现使用 JSON 路径,wiremock 由于格式不正确而无法匹配请求正文。例如,这样的请求:
{
animal {
type {
key1: "value"
key2: value2
}
}
}
Run Code Online (Sandbox Code Playgroud)
代替
{
"animal":{
"type":{
"key1":"value",
"key2":"value2"
}
}
}
Run Code Online (Sandbox Code Playgroud)
可以说key1=value1应该匹配并且response1.json应该返回,或者当key1=时someOtherValue,response2.json应该返回。是的,钥匙是类型的一部分,而类型是动物的一部分。我怎样才能实现这个请求正文匹配?
我是新来的WireMock. 我将WireMock服务器作为独立进程运行。我可以通过配置/mappings文件夹下的 json 文件来模拟简单的 REST API。现在,我想模拟一个文件下载端点。我怎样才能做到这一点?
我不知道它是否有帮助,终点是在 Java/Spring 中,如下所示:
@RequestMapping(value = "xxx/get", method = {RequestMethod.GET})
public ResponseEntity<Object> getFile(HttpServletResponse response) throws Exception {
final Resource fileResource = fileResourceFactoryBean.getObject();
if (fileResource.exists()) {
try (InputStream inputStream = fileResource.getInputStream()) {
IOUtils.copy(inputStream, response.getOutputStream());
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=" + fileResource.getFilename());
response.flushBuffer();
inputStream.close();
return new ResponseEntity<>(HttpStatus.OK);
} catch (Exception e) {
LOGGER.error("Error reading file: ", e);
return new ResponseEntity<Object>("Error reading file.", HttpStatus.BAD_REQUEST);
}
}
return new ResponseEntity<Object>(fileResource.getFilename() + " not found.", …Run Code Online (Sandbox Code Playgroud) 我需要使用wiremock 来测试发送数据的POST 请求,如下所示:
{
"name": "known fixed value",
"dateOfBirth": 5123456789000,
"email": "known fixed value",
"currentDate": any numeric value,
"status": any text value with alphabets, numbers and symbols
}
Run Code Online (Sandbox Code Playgroud)
前 3 个字段(姓名、出生日期和电子邮件)是固定的已知值,不会从一个请求到下一个请求而改变。
最后 2 个字段(currentDate 和 status)从一个请求到下一个请求随机变化,但它们是强制字段,可以保存任何值。
我如何设计一个测试这个的映射?
提前致谢。
假设应用程序依赖于外部服务器http://otherserver.com上的REST 服务。为了进行测试,我想在 JUnit 环境中模拟外部休息调用(通过 Wiremock)。启动单独的服务器既耗时又不容易。使用 WiremockRule 看起来是正确的方向。创建模拟控制器并不是一种优雅的方式,因为可以使用 Wiremock。
例如 get(" http://otherserver.com/service3/ ");
PS:我当然知道我可以通过 Mockito 模拟 REST 调用。
使用 Wiremock 模拟 localhost 很容易。我如何使用该代码来模拟其他服务器和服务?我从流行的 Baeldung 示例中复制了部分内容。
public class WireMockDemo {
@Rule
public WireMockRule wireMockRule = new WireMockRule();
@Test
public void wireMockTestJunitOtherServer() {
try {
// **this does not work...**
configureFor("otherserver.com", 8080);
stubFor(get(urlPathMatching("/service2/.*"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("\"testing-library\": \"WireMock\"")));
// Test via simple client
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet("http://otherserver:8080/service2/test");
HttpResponse httpResponse = httpClient.execute(request); …Run Code Online (Sandbox Code Playgroud) 我在实现此项目的 servlet 上运行 Wiremock,来自https://github.com/tomakehurst/wiremock/tree/master/sample-war
我能够将其部署到 Tomcat 中并使其正常工作。
现在,我想在此服务器上启用响应模板,以便我可以使用车把模板来调整响应正文。我看到了一些与 Junit 规则相关的解决方案,直接从代码和独立服务器中进行设置,但找不到从 servlet 启用响应模板的解决方案。
如何从wiremock servlet 启用此功能?
我正在使用 wiremock 来模拟某些请求及其各自的响应,但我正在尝试添加一个正则表达式。不幸的是,这只是抛出一个异常,指出请求不匹配。
{
"request" : {
"method": "GET",
"urlPattern": "/my/service/url?^.*(specificParam.*(M[0-9]{9})).*$"
},
"response": {
...
}
}
Run Code Online (Sandbox Code Playgroud)
我也试过
"urlPattern": "/my/service/url\\?^.*(specificParam.*(M[0-9]{9})).*$"
Run Code Online (Sandbox Code Playgroud)
我发送的请求是
/my/service/url?saml2=disabled&filter=specificParam%20eq%20%27M012345678%27
有谁知道为什么请求与映射不匹配?提前致谢。
@ClassRule
public static WireMockRule wireMockRule = new WireMockRule(9898);
@Test
public void createXmlFile() {
stubFor(get(urlPathEqualTo("/data/racing/"))
.willReturn(aResponse()
.withBody(loadJSONFile("unibet-demo-input.json"))));
}
Run Code Online (Sandbox Code Playgroud)
我不知道这里出了什么问题!
2019-01-16 15:54:05.810 [qtp1929284175-20] INFO ROOT:2341 - RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.StubRequestHandler. Normalized mapped under returned 'null'
2019-01-16 15:54:05.822 [qtp1929284175-15] INFO __admin:2341 - RequestHandlerClass from context returned com.github.tomakehurst.wiremock.http.AdminRequestHandler. Normalized mapped under returned 'null'
2019-01-16 15:54:05.925 [qtp1929284175-20] ERROR WireMock:40 - Request was not matched as there were no stubs registered:
{
"url" : "/data/racing/",
"absoluteUrl" : "http://localhost:9898/data/racing/",
"method" : "GET",
"clientIp" : "127.0.0.1",
"headers" …Run Code Online (Sandbox Code Playgroud) 我有以下场景:
@Transactional
@SpringBootTest
@ActiveProfiles("test")
@AutoConfigureMockMvc
@AutoConfigureWireMock(port = 0)
public abstract class IntegrationTest {
}
public class Test1 extends IntegrationTest {
// Tests that use WireMock
}
@ActiveProfiles("specific-case-test") // This causes another Application Context to be created.
public class Test2 extends IntegrationTest {
// Tests that use WireMock
}
public class Test3 extends IntegrationTest {
// Tests that use WireMock
}
Run Code Online (Sandbox Code Playgroud)
测试在所有这些场景中成功运行:
在所有这些情况下,最后运行的测试都会失败:
我已经调查过这个问题,它与 Spring Application Context 和 WireMock 有关。
到底是怎么回事?让我们考虑测试按以下顺序运行:Test1, Test2, Test3 …
wiremock ×10
java ×5
spring-boot ×3
mocking ×2
spring ×2
feign ×1
json ×1
jsonpath ×1
regex ×1
servlets ×1
spring-cloud ×1
spring-mvc ×1
tomcat ×1
url-pattern ×1