6

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 ?

4
  • could it be that you actually have to do an http action somewhere between the "stub" and "verify" steps for the latter not to fail? Commented May 27, 2018 at 12:12
  • @MykolaGurov, I really don't any idea. weather i have to implement something. as i'm mocking the request.
    – NarendraR
    Commented May 29, 2018 at 8:12
  • WireMock mocks server response, not the request. If you need to mock request then you probably looking for something like rest-assured.io Commented May 29, 2018 at 8:41
  • @MykolaGurov, actually i want to mock server response. Like in above code i have created on stub. Now i want to verify the response return by server it is returning [ ] and giving the mentioned errer . Just want mocking don't want to perform any real time request to some service and verify the response
    – NarendraR
    Commented May 29, 2018 at 9:24

2 Answers 2

7
+50

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")));
}
1
  • Yes you are right. I was missing that i have to send a request after create the stub for that.
    – NarendraR
    Commented Jun 7, 2018 at 5:21
0

Kindly, recommend using a class rule annotation/field (@ClassRule) for JUnit 4 (in those cases, where config could be reused on multiple unit tests).

@Rule could cause unexpected behaviors on async or http requests contexts, when stubs aren't registered yet.

Versions: 2.21.0 -> ... -> 2.31.0.

Note: In my particular case, had multiple tests reusing config and all the requests where executed correctly (debugging & checking mocked responses deserialized onto in-memory DTOs).

Then:

// ... WIREMOCK_PORT

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

Also, recommend verifying mocked request was made to WireMock registered stubs.

Steps:

  1. Create stub: WIRE_MOCK_RULE.stubFor(get(urlPathMatching(...))) // get, post, ...
  2. Hit mocked endpoint with a Http client
  3. Verify stub was invoked: verify(getRequestedFor(urlPathMatching(...)))
//{get, post, ...}RequestedFor(...) API methods for a particular HTTP request

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.