com.github.tomakehurst.wiremock.StubbingAcceptanceTest.java Source code

Java tutorial

Introduction

Here is the source code for com.github.tomakehurst.wiremock.StubbingAcceptanceTest.java

Source

/*
 * Copyright (C) 2011 Thomas Akehurst
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.tomakehurst.wiremock;

import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.admin.model.ListStubMappingsResult;
import com.github.tomakehurst.wiremock.stubbing.StubMapping;
import com.github.tomakehurst.wiremock.testsupport.WireMockResponse;
import org.apache.http.MalformedChunkCodingException;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.UUID;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.http.RequestMethod.GET;
import static com.github.tomakehurst.wiremock.http.RequestMethod.POST;
import static com.github.tomakehurst.wiremock.testsupport.TestHttpHeader.withHeader;
import static java.net.HttpURLConnection.HTTP_NOT_FOUND;
import static java.net.HttpURLConnection.HTTP_OK;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

public class StubbingAcceptanceTest extends AcceptanceTestBase {

    @BeforeClass
    public static void setupServer() {
        setupServerWithMappingsInFileRoot();
    }

    @Test
    public void mappingWithExactUrlAndMethodMatch() {
        stubFor(get(urlEqualTo("/a/registered/resource")).willReturn(
                aResponse().withStatus(401).withHeader("Content-Type", "text/plain").withBody("Not allowed!")));

        WireMockResponse response = testClient.get("/a/registered/resource");

        assertThat(response.statusCode(), is(401));
        assertThat(response.content(), is("Not allowed!"));
        assertThat(response.firstHeader("Content-Type"), is("text/plain"));
    }

    @Test
    public void mappingWithUrlContainingQueryParameters() {
        stubFor(get(urlEqualTo("/search?name=John&postcode=N44LL"))
                .willReturn(aResponse().withHeader("Location", "/nowhere").withStatus(302)));

        WireMockResponse response = testClient.get("/search?name=John&postcode=N44LL");

        assertThat(response.statusCode(), is(302));
    }

    @Test
    public void mappingWithHeaderMatchers() {
        stubFor(put(urlEqualTo("/some/url")).withHeader("One", equalTo("abcd1234"))
                .withHeader("Two", matching("[a-z]{5}")).withHeader("Three", notMatching("[A-Z]+"))
                .willReturn(aResponse().withStatus(204)));

        WireMockResponse response = testClient.put("/some/url", withHeader("One", "abcd1234"),
                withHeader("Two", "thing"), withHeader("Three", "something"));

        assertThat(response.statusCode(), is(204));
    }

    @Test
    public void mappingWithCaseInsensitiveHeaderMatchers() {
        stubFor(put(urlEqualTo("/case/insensitive")).withHeader("ONE", equalTo("abcd1234"))
                .withHeader("two", matching("[a-z]{5}")).withHeader("Three", notMatching("[A-Z]+"))
                .willReturn(aResponse().withStatus(204)));

        WireMockResponse response = testClient.put("/case/insensitive", withHeader("one", "abcd1234"),
                withHeader("TWO", "thing"), withHeader("tHrEe", "something"));

        assertThat(response.statusCode(), is(204));
    }

    @Test
    public void doesNotMatchOnAbsentHeader() {
        stubFor(post(urlEqualTo("/some/url")).withRequestBody(containing("BODY"))
                .withHeader("NoSuchHeader", equalTo("This better not be here"))
                .willReturn(aResponse().withStatus(200)));

        assertThat(testClient.postWithBody("/some/url", "BODY", "text/plain", "utf-8").statusCode(), is(404));
    }

    @Test
    public void matchesIfRequestContainsHeaderNotSpecified() {
        stubFor(get(urlEqualTo("/some/extra/header")).withHeader("ExpectedHeader", equalTo("expected-value"))
                .willReturn(aResponse().withStatus(200)));

        WireMockResponse response = testClient.get("/some/extra/header",
                withHeader("ExpectedHeader", "expected-value"), withHeader("UnexpectedHeader", "unexpected-value"));

        assertThat(response.statusCode(), is(200));
    }

    @Test
    public void matchesOnUrlPathAndQueryParameters() {
        stubFor(get(urlPathEqualTo("/path-and-query/match")).withQueryParam("search", containing("WireMock"))
                .withQueryParam("since", equalTo("2014-10-14")).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/path-and-query/match?since=2014-10-14&search=WireMock%20stubbing").statusCode(),
                is(200));
    }

    @Test
    public void doesNotMatchOnUrlPathWhenExtraPathElementsPresent() {
        stubFor(get(urlPathEqualTo("/matching-path")).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/matching-path/extra").statusCode(), is(404));
    }

    @Test
    public void doesNotMatchOnUrlPathWhenPathShorter() {
        stubFor(get(urlPathEqualTo("/matching-path")).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/matching").statusCode(), is(404));
    }

    @Test
    public void matchesOnUrlPathPatternAndQueryParameters() {
        stubFor(get(urlPathMatching("/path(.*)/match")).withQueryParam("search", containing("WireMock"))
                .withQueryParam("since", equalTo("2014-10-14")).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/path-and-query/match?since=2014-10-14&search=WireMock%20stubbing").statusCode(),
                is(200));
    }

    @Test
    public void doesNotMatchOnUrlPathPatternWhenPathShorter() {
        stubFor(get(urlPathMatching("/matching-path")).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/matching").statusCode(), is(404));
    }

    @Test
    public void doesNotMatchOnUrlPathPatternWhenExtraPathPresent() {
        stubFor(get(urlPathMatching("/matching-path")).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/matching-path/extra").statusCode(), is(404));
    }

    @Test
    public void doesNotMatchIfSpecifiedQueryParameterNotInRequest() {
        stubFor(get(urlPathEqualTo("/path-and-query/match")).withQueryParam("search", containing("WireMock"))
                .willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/path-and-query/match?wrongParam=wrongVal").statusCode(), is(404));
    }

    @Test
    public void doesNotMatchIfSpecifiedAbsentQueryParameterIsPresentInRequest() {
        stubFor(get(urlPathEqualTo("/path-and-query/match")).withQueryParam("search", absent())
                .willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/path-and-query/match?search=presentwhoops").statusCode(), is(404));
    }

    @Test
    public void matchesIfSpecifiedAbsentQueryParameterIsAbsentFromRequest() {
        stubFor(get(urlPathEqualTo("/path-and-query/match")).withQueryParam("search", absent())
                .willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/path-and-query/match?anotherparam=present").statusCode(), is(200));
    }

    @Test
    public void responseBodyLoadedFromFile() {
        stubFor(get(urlEqualTo("/my/file"))
                .willReturn(aResponse().withStatus(200).withBodyFile("plain-example.txt")));

        WireMockResponse response = testClient.get("/my/file");

        assertThat(response.content(), is("Some example test from a file"));
    }

    @Test
    public void matchingOnRequestBodyWithTwoRegexes() {
        stubFor(put(urlEqualTo("/match/this/body")).withRequestBody(matching(".*Blah.*"))
                .withRequestBody(matching(".*@[0-9]{5}@.*"))
                .willReturn(aResponse().withStatus(HTTP_OK).withBodyFile("plain-example.txt")));

        WireMockResponse response = testClient.putWithBody("/match/this/body", "Blah...but not the rest",
                "text/plain");
        assertThat(response.statusCode(), is(HTTP_NOT_FOUND));
        response = testClient.putWithBody("/match/this/body", "@12345@...but not the rest", "text/plain");
        assertThat(response.statusCode(), is(HTTP_NOT_FOUND));

        response = testClient.putWithBody("/match/this/body", "BlahBlah@56565@Blah", "text/plain");
        assertThat(response.statusCode(), is(HTTP_OK));
    }

    @Test
    public void matchingOnRequestBodyWithAContainsAndANegativeRegex() {
        stubFor(put(urlEqualTo("/match/this/body/too")).withRequestBody(containing("Blah"))
                .withRequestBody(notMatching(".*[0-9]+.*"))
                .willReturn(aResponse().withStatus(HTTP_OK).withBodyFile("plain-example.txt")));

        WireMockResponse response = testClient.putWithBody("/match/this/body/too", "Blah12345", "text/plain");
        assertThat(response.statusCode(), is(HTTP_NOT_FOUND));

        response = testClient.putWithBody("/match/this/body/too", "BlahBlahBlah", "text/plain");
        assertThat(response.statusCode(), is(HTTP_OK));
    }

    @Test
    public void matchingOnRequestBodyWithEqualTo() {
        stubFor(put(urlEqualTo("/match/this/body/too")).withRequestBody(equalTo("BlahBlahBlah"))
                .willReturn(aResponse().withStatus(HTTP_OK).withBodyFile("plain-example.txt")));

        WireMockResponse response = testClient.putWithBody("/match/this/body/too", "Blah12345", "text/plain");
        assertThat(response.statusCode(), is(HTTP_NOT_FOUND));

        response = testClient.putWithBody("/match/this/body/too", "BlahBlahBlah", "text/plain");
        assertThat(response.statusCode(), is(HTTP_OK));
    }

    @Test
    public void responseWithFixedDelay() {
        stubFor(get(urlEqualTo("/delayed/resource"))
                .willReturn(aResponse().withStatus(200).withBody("Content").withFixedDelay(500)));

        long start = System.currentTimeMillis();
        testClient.get("/delayed/resource");
        int duration = (int) (System.currentTimeMillis() - start);

        assertThat(duration, greaterThanOrEqualTo(500));
    }

    @Test
    public void responseWithLogNormalDistributedDelay() {
        stubFor(get(urlEqualTo("/lognormal/delayed/resource"))
                .willReturn(aResponse().withStatus(200).withBody("Content").withLogNormalRandomDelay(90, 0.1)));

        long start = System.currentTimeMillis();
        testClient.get("/lognormal/delayed/resource");
        int duration = (int) (System.currentTimeMillis() - start);

        assertThat(duration, greaterThanOrEqualTo(60));
    }

    @Test
    public void responseWithUniformDistributedDelay() {
        stubFor(get(urlEqualTo("/uniform/delayed/resource"))
                .willReturn(aResponse().withStatus(200).withBody("Content").withUniformRandomDelay(50, 60)));

        long start = System.currentTimeMillis();
        testClient.get("/uniform/delayed/resource");
        int duration = (int) (System.currentTimeMillis() - start);

        assertThat(duration, greaterThanOrEqualTo(50));
    }

    @Test
    public void highPriorityMappingMatchedFirst() {
        stubFor(get(urlMatching("/priority/.*")).atPriority(10).willReturn(aResponse().withStatus(500)));
        stubFor(get(urlEqualTo("/priority/resource")).atPriority(2).willReturn(aResponse().withStatus(200)));

        assertThat(testClient.get("/priority/resource").statusCode(), is(200));
    }

    @Test
    public void emptyResponseFault() {
        stubFor(get(urlEqualTo("/empty/response")).willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE)));

        getAndAssertUnderlyingExceptionInstanceClass("/empty/response", NoHttpResponseException.class);
    }

    @Test
    public void malformedResponseChunkFault() {
        stubFor(get(urlEqualTo("/malformed/response"))
                .willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));

        getAndAssertUnderlyingExceptionInstanceClass("/malformed/response", MalformedChunkCodingException.class);
    }

    @Test
    public void randomDataOnSocketFault() {
        stubFor(get(urlEqualTo("/random/data")).willReturn(aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE)));

        getAndAssertUnderlyingExceptionInstanceClass("/random/data", ClientProtocolException.class);
    }

    @Test
    public void matchingUrlsWithEscapeCharacters() {
        stubFor(get(urlEqualTo("/%26%26The%20Lord%20of%20the%20Rings%26%26"))
                .willReturn(aResponse().withStatus(HTTP_OK)));
        assertThat(testClient.get("/%26%26The%20Lord%20of%20the%20Rings%26%26").statusCode(), is(HTTP_OK));
    }

    @Test
    public void default200ResponseWhenStatusCodeNotSpecified() {
        stubFor(get(urlEqualTo("/default/two-hundred")).willReturn(aResponse()));
        assertThat(testClient.get("/default/two-hundred").statusCode(), is(HTTP_OK));
    }

    @Test
    public void returningBinaryBody() {
        byte[] bytes = new byte[] { 65, 66, 67 };
        stubFor(get(urlEqualTo("/binary/content")).willReturn(aResponse().withBody(bytes)));

        assertThat(testClient.get("/binary/content").binaryContent(), is(bytes));
    }

    @Test
    public void listingAllStubMappings() {
        stubFor(get(urlEqualTo("/stub/one")).willReturn(aResponse().withBody("One")));
        stubFor(post(urlEqualTo("/stub/two")).willReturn(aResponse().withBody("Two").withStatus(201)));

        ListStubMappingsResult listingResult = listAllStubMappings();
        StubMapping mapping1 = listingResult.getMappings().get(0);
        assertThat(mapping1.getRequest().getMethod(), is(POST));
        assertThat(mapping1.getRequest().getUrl(), is("/stub/two"));
        assertThat(mapping1.getResponse().getBody(), is("Two"));
        assertThat(mapping1.getResponse().getStatus(), is(201));

        StubMapping mapping2 = listingResult.getMappings().get(1);
        assertThat(mapping2.getRequest().getMethod(), is(GET));
        assertThat(mapping2.getRequest().getUrl(), is("/stub/one"));
        assertThat(mapping2.getResponse().getBody(), is("One"));
    }

    @Test
    public void stubbingPatch() {
        stubFor(patch(urlEqualTo("/a/registered/resource")).withRequestBody(equalTo("some body"))
                .willReturn(aResponse().withStatus(204)));

        WireMockResponse response = testClient.patchWithBody("/a/registered/resource", "some body", "text/plain");

        assertThat(response.statusCode(), is(204));
    }

    @Test
    public void stubbingArbitraryMethod() {
        stubFor(request("KILL", urlEqualTo("/some/url")).willReturn(aResponse().withStatus(204)));

        WireMockResponse response = testClient.request("KILL", "/some/url");

        assertThat(response.statusCode(), is(204));
    }

    @Test
    public void settingStatusMessage() {
        stubFor(get(urlEqualTo("/status-message"))
                .willReturn(aResponse().withStatus(500).withStatusMessage("The bees! They're in my eyes!")));

        assertThat(testClient.get("/status-message").statusMessage(), is("The bees! They're in my eyes!"));
    }

    @Test
    public void doesNotAttemptToMatchXmlBodyWhenStubMappingDoesNotHaveOne() {
        stubFor(options(urlEqualTo("/no-body")).willReturn(aResponse().withStatus(200)));
        stubFor(post(urlEqualTo("/no-body")).withRequestBody(equalToXml("<some-xml />"))
                .willReturn(aResponse().withStatus(201)));

        WireMockResponse response = testClient.request("OPTIONS", "/no-body");
        assertThat(response.statusCode(), is(200));
    }

    @Test
    public void matchesQueryParamsUnencoded() {
        stubFor(get(urlPathEqualTo("/query")).withQueryParam("param-one", equalTo("one two three ?"))
                .willReturn(aResponse().withStatus(200)));

        WireMockResponse response = testClient.get("/query?param-one=one%20two%20three%20%3F");
        assertThat(response.statusCode(), is(200));
    }

    @Test
    public void copesWithEmptyRequestHeaderValueWhenMatchingOnEqualTo() {
        stubFor(get(urlPathEqualTo("/empty-header")).withHeader("X-My-Header", equalTo(""))
                .willReturn(aResponse().withStatus(200)));

        WireMockResponse response = testClient.get("/empty-header", withHeader("X-My-Header", ""));

        assertThat(response.statusCode(), is(200));
    }

    @Test
    public void assignsAnIdAndReturnsNewlyCreatedStubMapping() {
        StubMapping stubMapping = stubFor(get(anyUrl()).willReturn(aResponse()));
        assertThat(stubMapping.getId(), notNullValue());

        StubMapping localStubMapping = wm.stubFor(get(anyUrl()).willReturn(aResponse()));
        assertThat(localStubMapping.getId(), notNullValue());
    }

    @Test
    public void getsASingleStubMappingById() {
        UUID id = UUID.randomUUID();
        stubFor(get(anyUrl()).withId(id).willReturn(aResponse().withBody("identified!")));

        StubMapping fetchedMapping = getSingleStubMapping(id);

        assertThat(fetchedMapping.getResponse().getBody(), is("identified!"));
    }

    @Test
    public void defaultsResponseWhenUnspecifiied() {
        stubFor(any(anyUrl()));

        assertThat(testClient.get("/anything-is-matched").statusCode(), is(200));
    }

    private void getAndAssertUnderlyingExceptionInstanceClass(String url, Class<?> expectedClass) {
        boolean thrown = false;
        try {
            WireMockResponse response = testClient.get(url);
            response.content();
        } catch (Exception e) {
            assertThat(e.getCause(), instanceOf(expectedClass));
            thrown = true;
        }

        assertTrue("No exception was thrown", thrown);
    }
}