You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/05/20 21:40:38 UTC
[juneau] branch master updated: Documentation.
This is an automated email from the ASF dual-hosted git repository.
jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push:
new a7e537a Documentation.
a7e537a is described below
commit a7e537abf215f9026bbb8e67f83c42235aa684ee
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sun May 20 17:40:23 2018 -0400
Documentation.
---
.../apache/juneau/utils/MockHttpConnection.java | 1 -
juneau-doc/src/main/javadoc/overview.html | 202 ++++++++++++++++++++-
.../java/org/apache/juneau/rest/mock/MockRest.java | 12 +-
.../juneau/rest/mock/MockServletRequest.java | 142 +++++++--------
4 files changed, 268 insertions(+), 89 deletions(-)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MockHttpConnection.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MockHttpConnection.java
index 388c5d3..38fb5d6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MockHttpConnection.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/MockHttpConnection.java
@@ -31,5 +31,4 @@ public interface MockHttpConnection {
* @throws Exception
*/
MockHttpRequest request(String method, String path, Object body) throws Exception;
-
}
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index fb54dd8..4fe0f12 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -327,6 +327,7 @@
<li><p><a class='doclink' href='#juneau-rest-server.RemoteableProxiesServerSide'>Server Side</a></p>
<li><p><a class='doclink' href='#juneau-rest-server.RemoteableProxiesRemoteableAnnotation'>@Remoteable Annotation</a></p>
</ol>
+ <li><p><a class='doclink' href='#juneau-rest-server.UnitTesting'>Server-less Unit Testing of REST Interfaces</a></p>
<li><p><a class='doclink' href='#juneau-rest-server.Injection'>Using with Spring and Injection frameworks</a></p>
<li><p><a class='doclink' href='#juneau-rest-server.HTTP2'>Using HTTP/2 features</a></p>
<li><p><a class='doclink' href='#juneau-rest-server.PredefinedHelperBeans'>Predefined Helper Beans</a></p>
@@ -15375,8 +15376,196 @@
</div>
<!-- ======================================================================================================= -->
+ <a id='juneau-rest-server.UnitTesting'></a>
+ <h3 class='topic' onclick='toggle(this)'>7.33 - Server-less Unit Testing of REST Interfaces</h3>
+ <div class='topic'>
+ <p>
+ The {@link org.apache.juneau.rest.mock.MockRest} class is a simple yet powerful interface for creating serverless
+ unit tests for your REST interfaces.
+ </p>
+ <p>
+ The following shows a self-encapsulated standalone JUnit testcase that tests the functionality of a simple REST interface.
+ </p>
+ <h5 class='figure'>Example:</h5>
+ <p class='bcode w800'>
+ <jk>public class</jk> MockTest {
+
+ <jc>// Our REST resource to test.</jc>
+ <ja>@RestResource</ja>(serializers=JsonSerializer.Simple.<jk>class</jk>, parsers=JsonParser.<jk>class</jk>)
+ <jk>public static class</jk> MyRest {
+
+ <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/String"</js>)
+ <jk>public</jk> String echo(<ja>@Body</ja> String b) {
+ <jk>return</jk> b;
+ }
+ }
+
+ <ja>@Test</ja>
+ <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
+ MockRest.<jsf>create</jsf>(MyRest.<jk>class</jk>).put(<js>"/String"</js>, <js>"'foo'"</js>).execute().assertStatus(200).assertBody(<js>"'foo'"</js>));
+ }
+ }
+ </p>
+ <p>
+ The API consists of the following classes:
+ </p>
+ <ul class='doctree'>
+ <li class='jp'>{@link org.apache.juneau.rest.mock}
+ <ul>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockRest}
+ <br>The API for instantiating mocks of REST resource classes.
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockServletRequest}
+ <br>An implementation of {@link javax.servlet.http.HttpServletRequest} with additional convenience methods for building requests.
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockServletResponse}
+ <br>An implementation of {@link javax.servlet.http.HttpServletRequest} with additional convenience methods for testing responses.
+ </ul>
+ </ul>
+ <p>
+ The concept of the design is simple. The {@link org.apache.juneau.rest.mock.MockRest} class is used to create instances of {@link org.apache.juneau.rest.mock.MockServletRequest}
+ and {@link org.apache.juneau.rest.mock.MockServletResponse} which are passed directly to the call handler on the resource class {@link org.apache.juneau.rest.RestCallHandler#service(HttpServletRequest,HttpServletResponse)}.
+ </p>
+ <p>
+ Breaking apart the fluent method call above will help you understand how this works.
+ </p>
+ <p class='bcode w800'>
+ <ja>@Test</ja>
+ <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
+
+ <jc>// Instantiate our mock.</jc>
+ MockRest mr = MockRest.<jsf>create</jsf>(MyRest.<jk>class</jk>);
+
+ <jc>// Create a request.</jc>
+ MockServletRequest req = mr.put(<js>"/String"</js>, <js>"'foo'"</js>);
+
+ <jc>// Execute it (by calling RestCallHandler.service(...) and then returning the response object).</jc>
+ MockServletResponse res = req.execute();
+
+ <jc>// Run assertion tests on the results.</jc>
+ res.assertStatus(200);
+ res.assertBody(<js>"'foo'"</js>);
+ }
+ </p>
+ <p>
+ The {@link org.apache.juneau.rest.mock.MockRest} class provides the following methods for creating requests:
+ </p>
+ <ul class='doctree'>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockRest}
+ <ul>
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#request(String,String) request(String,String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#request(String,String,Object) request(String,String,Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#get(String) get(String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#put(String,Object) put(String,Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#post(String,Object) post(String,Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#delete(String) delete(String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockRest#options(String) options(String)}
+ </ul>
+ </ul>
+ <p>
+ The {@link org.apache.juneau.rest.mock.MockServletRequest} class provides default implementations for all the methods defined
+ on the {@link javax.servlet.http.HttpServletRequest} in addition to many convenience methods.
+ </p>
+ <p>
+ The following fluent convenience methods are provided for setting common <code>Accept</code> and <code>Content-Type</code> headers.
+ </p>
+ <ul class='doctree'>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockServletRequest}
+ <ul>
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#json() json()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#xml() xml()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#html() html()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#plainText() plainText()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#msgpack() msgpack()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#uon() uon()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#urlEnc() urlEnc()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#yaml() yaml()}
+ </ul>
+ </ul>
+ <p>
+ The following fluent convenience methods are provided for building up your request.
+ </p>
+ <ul class='doctree'>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockServletRequest}
+ <ul>
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#header(String,Object) header(String,Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#query(String,Object) query(String,Object}}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#formData(String,Object) formData(String,Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#attribute(String,Object) attribute(String,Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#body(Object) body(Object)}
+ </ul>
+ </ul>
+ <p>
+ Fluent setters are provided for all common request headers:
+ </p>
+ <ul class='doctree'>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockServletRequest}
+ <ul>
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#accept(Object) accept(Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#acceptCharset(Object) acceptCharset(Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#acceptEncoding(Object) acceptEncoding(Object)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletRequest#acceptLanguage(Object) acceptLanguage(Object)}
+ <li class='jm'>...
+ </ul>
+ </ul>
+ <p>
+ The {@link org.apache.juneau.rest.mock.MockServletResponse} class provides default implementations for all the methods defined
+ on the {@link javax.servlet.http.HttpServletResponse} in addition to many convenience methods.
+ </p>
+ <ul class='doctree'>
+ <li class='jc'>{@link org.apache.juneau.rest.mock.MockServletResponse}
+ <ul>
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#getBody() getBody()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#getBodyAsString() getBodyAsString()}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertStatus(int) assertStatus(int)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertBody(String) assertBody(String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertBodyContains(String...) assertBodyContains(String...)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertBodyMatches(String) assertBodyMatches(String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertBodyMatchesRE(String) assertBodyMatchesRE(String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertHeader(String,String) assertHeader(String,String)}
+ <li class='jm'>{@link org.apache.juneau.rest.mock.MockServletResponse#assertHeaderContains(String,String...) assertHeaderContains(String,String...)}
+ </ul>
+ </ul>
+ <p>
+ The {@link org.apache.juneau.rest.mock.MockRest} object can also be used with the {@link org.apache.juneau.rest.client.RestClient} class to
+ perform server-less unit testing through the client API of REST resources.
+ <br>This can be useful for testing of interface proxies against REST interfaces (described later).
+ </p>
+ <p>
+ The example above can be rewritten to use a mock as follows:
+ </p>
+ <h5 class='figure'>Example:</h5>
+ <p class='bcode w800'>
+ <jk>public class</jk> MockTest {
+
+ <jc>// Our REST resource to test.</jc>
+ <ja>@RestResource</ja>(serializers=JsonSerializer.Simple.<jk>class</jk>, parsers=JsonParser.<jk>class</jk>)
+ <jk>public static class</jk> MyRest {
+
+ <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/String"</js>)
+ <jk>public</jk> String echo(<ja>@Body</ja> String b) {
+ <jk>return</jk> b;
+ }
+ }
+
+ <ja>@Test</ja>
+ <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
+ MockRest mr = MockRest.<jsm>create</jsm>(MyRest.<jk>class</jk>);
+ RestClient rc = RestClient.<jsm>create</jsm>().mockHttpConnection(mr).build();
+ <jsm>assertEquals</jsm>(<js>"'OK'"</js>, rc.doPut(<js>"/String"</js>, <js>"'OK'"</js>).getResponseAsString());
+ }
+ }
+ </p>
+ <p>
+ The {@link org.apache.juneau.rest.client.RestClientBuilder#mockHttpConnection(MockHttpConnection)} method allows you to pass in a mocked
+ interface for creating HTTP requests through the client interface.
+ <br>The method creates a specialized <code>HttpClientConnectionManager</code> for handling requests by taking information on the
+ client-side request and populating the {@link org.apache.juneau.rest.mock.MockServletRequest} and {@link org.apache.juneau.rest.mock.MockServletResponse} objects
+ directly without involving any sockets.
+ </p>
+ </div>
+
+ <!-- ======================================================================================================= -->
<a id='juneau-rest-server.Injection'></a>
- <h3 class='topic' onclick='toggle(this)'>7.33 - Using with Spring and Injection frameworks</h3>
+ <h3 class='topic' onclick='toggle(this)'>7.34 - Using with Spring and Injection frameworks</h3>
<div class='topic'>
<p>
The Juneau REST server API is compatible with dependency injection frameworks such as Spring.
@@ -15483,7 +15672,7 @@
<!-- ======================================================================================================= -->
<a id='juneau-rest-server.HTTP2'></a>
- <h3 class='topic' onclick='toggle(this)'>7.34 - Using HTTP/2 features</h3>
+ <h3 class='topic' onclick='toggle(this)'>7.35 - Using HTTP/2 features</h3>
<div class='topic'>
<p>
Juneau is built as a veneer on top of the Servlet API, allowing you to use low-level Servlet APIs
@@ -15498,7 +15687,7 @@
<!-- ======================================================================================================= -->
<a id='juneau-rest-server.PredefinedHelperBeans'></a>
- <h3 class='topic' onclick='toggle(this)'>7.35 - Predefined Helper Beans</h3>
+ <h3 class='topic' onclick='toggle(this)'>7.36 - Predefined Helper Beans</h3>
<div class='topic'>
<p>
The {@link org.apache.juneau.rest.helper} package contains some reusable beans that are useful for
@@ -15596,7 +15785,7 @@
<!-- ======================================================================================================== -->
<a id='juneau-rest-server.OtherNotes'></a>
- <h3 class='topic' onclick='toggle(this)'>7.36 - Other Notes</h3>
+ <h3 class='topic' onclick='toggle(this)'>7.37 - Other Notes</h3>
<div class='topic'>
<ul class='spaced-list'>
<li>
@@ -21526,6 +21715,9 @@
<ul>
<li class='jc'>{@link org.apache.juneau.rest.mock.MockRest}
</ul>
+ <li>
+ New documentation:
+ <br>><a class="doclink" href="#juneau-rest-server.UnitTesting">Overview > juneau-rest-server > Server-less Unit Testing of REST Interfaces</a>
</ul>
<h5 class='topic w800'>juneau-rest-client</h5>
@@ -21565,7 +21757,7 @@
New method added for allowing serverless client testing against REST interfaces.
<li class='jc'>{@link org.apache.juneau.rest.client.RestClientBuilder}
<ul>
- <li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#mockHttpConnection() mockHttpConnection(MockHttpConnection)}
+ <li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#mockHttpConnection(MockHttpConnection) mockHttpConnection(MockHttpConnection)}
</ul>
</ul>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
index dcab204..20de6fd 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockRest.java
@@ -24,13 +24,13 @@ import org.apache.juneau.utils.*;
* <p>
* Allows you to test your REST resource classes without a running servlet container.
*
- * <h5 class='section'>Example:</h5>
- * <p class='bcode'>
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
* <jk>public class</jk> MockTest {
*
* <jc>// Our REST resource to test.</jc>
* <ja>@RestResource</ja>(serializers=JsonSerializer.Simple.<jk>class</jk>, parsers=JsonParser.<jk>class</jk>)
- * <jk>public static class</jk> M {
+ * <jk>public static class</jk> MyRest {
*
* <ja>@RestMethod</ja>(name=<jsf>PUT</jsf>, path=<js>"/String"</js>)
* <jk>public</jk> String echo(<ja>@Body</ja> String b) {
@@ -38,15 +38,15 @@ import org.apache.juneau.utils.*;
* }
* }
*
- * <ja>@Test</js>
+ * <ja>@Test</ja>
* <jk>public void</jk> testEcho() <jk>throws</jk> Exception {
- * <jsm>assertEquals</jsm>(<js>"'foo'"</js>, MockRest.<jsf>create</jsf>(M.<jk>class</jk>).request(<js>"PUT"</js>, <js>"/String"</js>).body(<js>"'foo'"</js>).execute().getBodyAsString());
+ * MockRest.<jsf>create</jsf>(MyRest.<jk>class</jk>).put(<js>"/String"</js>, <js>"'foo'"</js>).execute().assertStatus(200).assertBody(<js>"'foo'"</js>));
* }
* </p>
*
* <h5 class='section'>See Also:</h5>
* <ul>
- * <li class='link'>TODO
+ * <li class='link'><a class="doclink" href="../../../../../overview-summary.html#juneau-rest-server.UnitTesting">Overview > juneau-rest-server > Server-less Unit Testing of REST Interfaces</a>
* </ul>
*/
public class MockRest implements MockHttpConnection {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
index 8cb567f..d6d8ba8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
@@ -239,78 +239,6 @@ public class MockServletRequest implements HttpServletRequest, MockHttpRequest {
/**
* Fluent setter.
*
- * @param name Query parameter name.
- * @param value Query parameter values.
- * @return This object (for method chaining).
- */
- public MockServletRequest param(String name, String[] value) {
- this.queryData.put(name, value);
- return this;
- }
-
- /**
- * Fluent setter.
- *
- * @param name Query parameter name.
- * @param value Query parameter value.
- * @return This object (for method chaining).
- */
- public MockServletRequest param(String name, String value) {
- this.queryData.put(name, new String[] {value});
- return this;
- }
-
- /**
- * Fluent setter.
- *
- * @param name Header name.
- * @param value Header value.
- * @return This object (for method chaining).
- */
- @Override /* MockHttpRequest */
- public MockServletRequest header(String name, Object value) {
- this.headerMap.put(name, new String[] {asString(value)});
- return this;
- }
-
- /**
- * Fluent setter.
- *
- * @param name Request attribute name.
- * @param value Request attribute value.
- * @return This object (for method chaining).
- */
- public MockServletRequest attribute(String name, Object value) {
- this.attributeMap.put(name, value);
- return this;
- }
-
- /**
- * Fluent setter.
- *
- * @param value The body of the request.
- * @return This object (for method chaining).
- */
- @Override /* MockHttpRequest */
- public MockServletRequest body(Object value) {
- try {
- if (value instanceof byte[])
- this.body = (byte[])value;
- if (value instanceof Reader)
- this.body = IOUtils.read((Reader)value).getBytes();
- if (value instanceof InputStream)
- this.body = IOUtils.readBytes((InputStream)value, 1024);
- if (value instanceof CharSequence)
- this.body = ((CharSequence)value).toString().getBytes();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- return this;
- }
-
- /**
- * Fluent setter.
- *
* @param value The character encoding.
* @return This object (for method chaining).
*/
@@ -1002,14 +930,73 @@ public class MockServletRequest implements HttpServletRequest, MockHttpRequest {
}
//=================================================================================================================
- // Convenience methods - query and form data
+ // Convenience methods
//=================================================================================================================
/**
- * Adds a form data entry to this request.
+ * Fluent setter.
+ *
+ * @param name Header name.
+ * @param value
+ * Header value.
+ * <br>The value is converted to a simple string using {@link Object#toString()}.
+ * @return This object (for method chaining).
+ */
+ @Override /* MockHttpRequest */
+ public MockServletRequest header(String name, Object value) {
+ this.headerMap.put(name, new String[] {asString(value)});
+ return this;
+ }
+
+ /**
+ * Fluent setter.
+ *
+ * @param name Request attribute name.
+ * @param value Request attribute value.
+ * @return This object (for method chaining).
+ */
+ public MockServletRequest attribute(String name, Object value) {
+ this.attributeMap.put(name, value);
+ return this;
+ }
+
+ /**
+ * Fluent setter.
*
- * @param key
* @param value
+ * The body of the request.
+ * <br>Can be any of the following data types:
+ * <ul>
+ * <li><code><jk>byte</jk>[]</code>
+ * <li>{@link Reader}
+ * <li>{@link InputStream}
+ * <li>{@link CharSequence}
+ * </ul>
+ * @return This object (for method chaining).
+ */
+ @Override /* MockHttpRequest */
+ public MockServletRequest body(Object value) {
+ try {
+ if (value instanceof byte[])
+ this.body = (byte[])value;
+ if (value instanceof Reader)
+ this.body = IOUtils.read((Reader)value).getBytes();
+ if (value instanceof InputStream)
+ this.body = IOUtils.readBytes((InputStream)value, 1024);
+ if (value instanceof CharSequence)
+ this.body = ((CharSequence)value).toString().getBytes();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ return this;
+ }
+
+ /**
+ * Adds a form data entry to this request.
+ *
+ * @param key The form data key.
+ * @param value The form data value.
+ * <br>The value is converted to a simple string using {@link Object#toString()}.
* @return This object (for method chaining).
*/
public MockServletRequest formData(String key, Object value) {
@@ -1028,8 +1015,9 @@ public class MockServletRequest implements HttpServletRequest, MockHttpRequest {
/**
* Adds a query data entry to this request.
*
- * @param key
- * @param value
+ * @param key The query key.
+ * @param value The query value.
+ * <br>The value is converted to a simple string using {@link Object#toString()}.
* @return This object (for method chaining).
*/
public MockServletRequest query(String key, Object value) {
--
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.