javajunitmockingwiremockservice-virtualization

com.github.tomakehurst.wiremock.client.VerificationException: Expected at least one request matching


I want to create a Stub for an API and want to verify API call and response returned by the server. for that i have implemented WireMock example :

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")));       }

}

But getting below error :

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)

If I comment verify part then test executed successfully also i have verified the same using postman by calling http://localhost:8080/login and it returning response successfully ?

Is any thing I'm missing here ?


Solution

  • In your code you are stubbing out a response and then verifying that a request has been made for that stub. You are not however making a call to the endpoint and so the test is failing.

    You need to invoke the endpoint before verifying that it is called.

    If you use Apache Commons HttpClient, you could write your test as:

    @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")));
    }