From c3c9ba21ad5801f95c1089a37d0bd9124a175c89 Mon Sep 17 00:00:00 2001 From: Chris Barrett Date: Wed, 31 Jul 2013 21:33:02 +0100 Subject: [PATCH] Added support for stubs as well as the existing expectations. --- .../com/pyruby/stubserver/Expectation.java | 6 ++- src/main/java/com/pyruby/stubserver/Stub.java | 19 +++++++++ .../com/pyruby/stubserver/StubServer.java | 17 ++++++++ .../com/pyruby/stubserver/StubServerTest.java | 41 +++++++++++++++---- 4 files changed, 73 insertions(+), 10 deletions(-) create mode 100644 src/main/java/com/pyruby/stubserver/Stub.java diff --git a/src/main/java/com/pyruby/stubserver/Expectation.java b/src/main/java/com/pyruby/stubserver/Expectation.java index 78f2fc1..22603b7 100644 --- a/src/main/java/com/pyruby/stubserver/Expectation.java +++ b/src/main/java/com/pyruby/stubserver/Expectation.java @@ -100,11 +100,15 @@ public void thenDelegate() { boolean matches(String target, HttpServletRequest httpServletRequest) { if (satisfied) return false; - boolean matched = stubbedMethod.matches(target, httpServletRequest); + boolean matched = stubMethodMatches(target, httpServletRequest); if (matched) satisfied = true; return matched; } + protected boolean stubMethodMatches(String target, HttpServletRequest httpServletRequest) { + return stubbedMethod.matches(target, httpServletRequest); + } + void verify() { if (!satisfied) { throw new AssertionError(stubbedMethod.toString()); diff --git a/src/main/java/com/pyruby/stubserver/Stub.java b/src/main/java/com/pyruby/stubserver/Stub.java new file mode 100644 index 0000000..b2c76b5 --- /dev/null +++ b/src/main/java/com/pyruby/stubserver/Stub.java @@ -0,0 +1,19 @@ +package com.pyruby.stubserver; + +import javax.servlet.http.HttpServletRequest; + +public class Stub extends Expectation { + public Stub(StubMethod stubMethod) { + super(stubMethod); + } + + @Override + boolean matches(String target, HttpServletRequest httpServletRequest) { + return stubMethodMatches(target, httpServletRequest); + } + + @Override + void verify() { + // Deliberately left blank + } +} diff --git a/src/main/java/com/pyruby/stubserver/StubServer.java b/src/main/java/com/pyruby/stubserver/StubServer.java index 49663cf..34ff736 100644 --- a/src/main/java/com/pyruby/stubserver/StubServer.java +++ b/src/main/java/com/pyruby/stubserver/StubServer.java @@ -124,6 +124,23 @@ public Expectation expect(StubMethod stubbedMethod) { return expectation; } + /** + * Specify the method, i.e. {@link StubMethod#get} including context path you expect your application + * to call. The resulting {@link Expectation} is used to allow you to specify what should happen when + * a subsequent request matches the stubbedMethod. + * + * This is different to expect(StubMethod) in that the StubMethod will match against multiple requests + * to the StubServer and will never fail verification. + * + * @param stubbedMethod {@link StubMethod} + * @return {@link Expectation} used to specify what happens when a request matches the stubbedMethod + */ + public Expectation stub(StubMethod stubbedMethod) { + Stub stub = new Stub(stubbedMethod); + expectations.add(stub); + return stub; + } + /** * Stops the {@link StubServer}. This should be in either a finally block, a unit test tear-down, or a class * tear-down. Using a class tear-down will make testing run much more quickly, but you will also need to diff --git a/src/test/java/com/pyruby/stubserver/StubServerTest.java b/src/test/java/com/pyruby/stubserver/StubServerTest.java index aebec2b..71812f3 100644 --- a/src/test/java/com/pyruby/stubserver/StubServerTest.java +++ b/src/test/java/com/pyruby/stubserver/StubServerTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import java.io.*; +import java.net.BindException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; @@ -41,7 +42,7 @@ public void start_shouldStartAWebServerOnTheDesignatedPort() throws IOException @Test public void expect_shouldAcceptAGetRequestToAUrlAndThenReturnTheExpectedResponse_withHeaders() throws IOException { server.expect(get("/my/expected/context")).thenReturn(200, "application/json", "My expected response", - headers(header("Set-Cookie", "c1=aaa"), header("Set-Cookie", "c2=bbb"))); + headers(header("Set-Cookie", "c1=aaa"), header("Set-Cookie", "c2=bbb"))); TestStubResponse response = makeRequest("/my/expected/context", "GET"); @@ -112,7 +113,7 @@ public void expect_shouldAcceptAGetRequestToAUrlAndThenReturnTheExpectedBytesRes } server.expect(get("/my/expected/context").ifContentType("application/octet\\-stream")) - .thenReturn(200, "application/octet-stream", res); + .thenReturn(200, "application/octet-stream", res); TestStubResponse response = makeRequest("/my/expected/context", "GET", "", "Content-Type", "application/octet-stream"); @@ -131,7 +132,7 @@ public void expect_shouldAcceptAPostRequestToAUrlAndThenReturnTheExpectedBytesRe } server.expect(post("/my/expected/context").ifContentType("application/octet-stream")) - .thenReturn(204, "application/octet-stream", ""); + .thenReturn(204, "application/octet-stream", ""); TestStubResponse response = makeRequest("/my/expected/context", "POST", req, "Content-Type", "application/octet-stream"); @@ -159,7 +160,7 @@ public void verify_shouldRaiseAnAssertionException_givenThereAreUnsatisfiedUrlEx @Test public void expect_shouldAcceptAGetRequestToAUrlThatMatchesAHeader() throws IOException { server.expect(get("/my/expected/context").ifHeader("x-test", "foobar")) - .thenReturn(200, "application/json", "My expected response"); + .thenReturn(200, "application/json", "My expected response"); makeRequest("/my/expected/context", "GET", "", "x-test", "foobar"); @@ -281,13 +282,35 @@ public void expectAndDelegateTo_shouldMatchAndPassTheCallToTheProxy() throws IOE } } + @Test + public void stub_matchesMoreThanOnce() throws IOException { + server.stub(StubMethod.get("/foo")).thenReturn(200, "text/plain", "You cannot be serious!"); + + TestStubResponse result1 = makeRequest("/foo", "GET"); + TestStubResponse result2 = makeRequest("/foo", "GET"); + + assertEquals(200, result1.responseCode); + assertEquals("You cannot be serious!", result1.bodyString()); + assertEquals(200, result2.responseCode); + assertEquals("You cannot be serious!", result2.bodyString()); + + server.verify(); + } + + @Test + public void stub_verifiesEvenIfNeverCalled() throws IOException { + server.stub(StubMethod.get("/foo")).thenReturn(200, "text/plain", "You cannot be serious!"); + + server.verify(); + } + private TestStubResponse makeRequest(String path, String method, Map query) throws IOException { StringBuilder body = new StringBuilder(); for (Map.Entry entry : query.entrySet()) { body.append(URLEncoder.encode(entry.getKey(), "UTF-8")) - .append("=") - .append(URLEncoder.encode(entry.getValue(), "UTF-8")) - .append('&'); + .append("=") + .append(URLEncoder.encode(entry.getValue(), "UTF-8")) + .append('&'); } body.deleteCharAt(body.length() - 1); return makeRequest(path, method, body.toString()); @@ -306,12 +329,12 @@ private TestStubResponse makeRequest(String path, String method, String body, St } private TestStubResponse makeRequest(String path, String method, String body, - String headerKey, String headerValue) throws IOException { + String headerKey, String headerValue) throws IOException { return makeRequest(path, method, Expectation.asBytes(body), headerKey, headerValue); } private TestStubResponse makeRequest(String path, String method, byte[] requestBody, - String headerKey, String headerValue) throws IOException { + String headerKey, String headerValue) throws IOException { URL url = new URL(baseUrl + path); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod(method);