【问题标题】:com.github.tomakehurst.wiremock.client.VerificationException: Expected at least one request matchingcom.github.tomakehurst.wiremock.client.VerificationException:预计至少有一个请求匹配
【发布时间】:2018-05-26 05:09:13
【问题描述】:

我想为 API 创建一个 Stub,并希望验证服务器返回的 API 调用和响应。为此我实施了WireMock 示例:

import org.junit.Rule;
import org.junit.Test;

import com.github.tomakehurst.wiremock.junit.WireMockRule;

public class MockTestDemo {

    private static final int WIREMOCK_PORT = 8080;

    @Rule
    public WireMockRule wireMockRule = new WireMockRule(WIREMOCK_PORT);

    @Test
    public void exampleTest() {

    stubFor(get(urlEqualTo("/login")).withHeader("Accept", equalTo("application/json"))
            .willReturn(aResponse().withStatus(200).withBody("Login Success")
                    .withStatusMessage("Everything was just fine!"))
            .willReturn(okJson("{ \"message\": \"Hello\" }")));

       verify(getRequestedFor(urlPathEqualTo("http://localhost:8080/login")) 
            .withHeader("Content-Type",equalTo("application/json")));       }

}

但出现以下错误:

com.github.tomakehurst.wiremock.client.VerificationException: Expected at least one request matching: {
  "urlPath" : "localhosturl/login",

   "method" : "GET",

  "headers" : {
    "Content-Type" : {
      "equalTo" : "application/json"
    }
  }
}

Requests received: [ ]
  at com.github.tomakehurst.wiremock.client.WireMock.verificationExceptionForNearMisses(WireMock.java:545)
  at com.github.tomakehurst.wiremock.client.WireMock.verifyThat(WireMock.java:532)
  at com.github.tomakehurst.wiremock.client.WireMock.verifyThat(WireMock.java:511)
  at com.github.tomakehurst.wiremock.client.WireMock.verify(WireMock.java:549)
  at com.wiremock.test.MockTestDemo.exampleTest(MockTestDemo.java:23)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
  at java.lang.reflect.Method.invoke(Unknown Source)
  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
  at com.github.tomakehurst.wiremock.junit.WireMockRule$1.evaluate(WireMockRule.java:73)
  at org.junit.rules.RunRules.evaluate(RunRules.java:20)
  at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
  at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
  at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
  at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
  at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)

如果我评论验证部分然后测试成功执行,我也通过调用http://localhost:8080/login 使用邮递员验证了相同的内容并成功返回响应?

我在这里缺少什么吗?

【问题讨论】:

  • 您是否实际上必须在“存根”和“验证”步骤之间的某处执行 http 操作,以使后者不会失败?
  • @MykolaGurov,我真的不知道。天气我必须实施一些事情。因为我在嘲笑这个请求。
  • WireMock 模拟服务器响应,而不是请求。如果您需要模拟请求,那么您可能正在寻找类似rest-assured.io
  • @MykolaGurov,实际上我想模拟服务器响应。就像上面我在 stub 上创建的代码一样。现在我想验证服务器返回的响应返回 [] 并给出提到的错误。只想模拟不想对某些服务执行任何实时请求并验证响应

标签: java junit mocking wiremock service-virtualization


【解决方案1】:

在您的代码中,您将响应存根,然后验证是否已针对该存根发出请求。但是,您没有调用端点,因此测试失败。

您需要先调用端点,然后再验证它是否被调用。

如果您使用 Apache Commons HttpClient,您可以将测试编写为:

@Test
public void exampleTest() throws Exception {

    stubFor(get(urlEqualTo("/login")).withHeader("Accept", equalTo("application/json"))
            .willReturn(aResponse().withStatus(200).withBody("Login Success")
                    .withStatusMessage("Everything was just fine!"))
            .willReturn(okJson("{ \"message\": \"Hello\" }")));

    String url = "http://localhost:8080/login";
    HttpClient client = HttpClientBuilder.create().build();
    HttpGet request = new HttpGet(url);
    request.addHeader("Content-Type", "application/json");
    request.addHeader("Accept", "application/json");
    HttpResponse response = client.execute(request);

    verify(getRequestedFor(urlPathEqualTo("/login"))
            .withHeader("Content-Type", equalTo("application/json")));
}

【讨论】:

  • 是的,你是对的。我错过了我必须在为此创建存根后发送请求。
【解决方案2】:

建议对JUnit 4 使用类规则注释/字段 (@ClassRule)(在这些情况下,配置可以在多个单元测试中重复使用 )。

stubs 尚未注册时,@Rule 可能会导致异步或 http 请求上下文出现意外行为。

版本: 2.21.0 -> ... -> 2.31.0

注意:在我的特殊情况下,有多个测试重用配置并且所有请求都正确执行(调试和检查反序列化到内存 DTO 上的模拟响应)。

然后:

// ... WIREMOCK_PORT

@ClassRule
public static final WireMockClassRule WIRE_MOCK_RULE = new WireMockClassRule(WIREMOCK_PORT);  // public

另外,建议验证已对 WireMock 注册的存根发出模拟请求。

步骤:

  1. 创建存根:WIRE_MOCK_RULE.stubFor(get(urlPathMatching(...))) // get, post, ...
  2. 使用 Http 客户端点击模拟端点
  3. 验证存根被调用:verify(getRequestedFor(urlPathMatching(...)))
//{get, post, ...}RequestedFor(...) API methods for a particular HTTP request

verify(getRequestedFor(urlPathMatching("a-url-pattern"))); //urlEqualTo, ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 2011-12-02
    • 2020-11-06
    • 2023-03-05
    • 2019-01-08
    相关资源
    最近更新 更多