javamockserver

Mockserver Request not found


I am currently trying to create expectations and get them verified by mockServer (can be found here).

I've read their documentation several times now but I can't find out why the verifcation of my expectation fails. This is my code

    @Rule
    public MockServerRule mockServerRule = new MockServerRule(this, 9000);

    private MockServerClient mockServer;

    @Test
    public void testVerification() {
        mockServer.when(
                HttpRequest.request()
                  .withMethod("POST")
                  .withPath("/validate")
                  .withHeader("\"Content-type\", \"application/json\"")
                  .withBody("{username: 'foo', password: 'bar'}"))
                  .respond(
                      HttpResponse.response()
                        .withStatusCode(401)
                        .withHeaders(
                          new Header("Content-Type", "application/json; charset=utf-8"),
                          new Header("Cache-Control", "public, max-age=86400"))
                        .withBody("{ message: 'incorrect username and password combination' }")
                        .withDelay(TimeUnit.SECONDS,1)
                    );

        mockServer.verify(HttpRequest.request().withMethod("POST")
                  .withPath("/validate")
                  .withBody("{username: 'foo', password: 'bar'}"),
                VerificationTimes.exactly(1));
    }

When trying to verify, I always get the error

java.lang.AssertionError: Request not found exactly once, expected:<{
  "method" : "POST",
  "path" : "/validate",
  "body" : "{username: 'foo', password: 'bar'}"}> but was:<>
    at org.mockserver.client.server.MockServerClient.verify(MockServerClient.java:267)
    at it.HttpTest.testVerification(HttpTest.java:61)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    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 org.mockserver.junit.MockServerRule$1.evaluate(MockServerRule.java:107)
    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:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)


Solution

  • Well, you forgot to send a request to your mock server. You only mocked its behaviour and then you check if the server has been called, but you missed the call.

    Try it with something like this:

    public int callValidateUrl() throws IOException {
        URL url = new URL("http://localhost:9000/validate");
    
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
    
        con.setDoOutput(true);
        String jsonInputString = "{username: 'foo', password: 'bar'}";
        try (OutputStream os = con.getOutputStream()) {
            byte[] input = jsonInputString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }
    
        return con.getResponseCode();
    }
    

    If you are using Spring, RestTemplate is easier to use.