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 c0457be  Better reusability of MockRestClient.
c0457be is described below

commit c0457be5cda07e04864523a13d224110a0ff0d19
Author: JamesBognar <james.bog...@salesforce.com>
AuthorDate: Mon Nov 16 11:51:52 2020 -0500

    Better reusability of MockRestClient.
---
 .../java/org/apache/juneau/PropertyStoreTest.java  |  1 +
 .../remote/Remote_RemoteMethodAnnotation_Test.java |  7 +---
 .../main/java/org/apache/juneau/PropertyStore.java |  2 +
 .../org/apache/juneau/assertions/Assertions.java   | 16 ++++++++
 .../client/RestClient_Config_Context_Test.java     |  6 ++-
 .../client/RestClient_Config_RestClient_Test.java  | 45 ++++++++++++++++----
 .../rest/client/RestClient_Marshalls_Test.java     |  7 ++--
 .../org/apache/juneau/rest/client/RestClient.java  | 48 +++++++++++++++++++++-
 .../juneau/rest/client/RestClientBuilder.java      | 10 +++--
 .../org/apache/juneau/rest/client/RestRequest.java | 16 ++++++++
 .../juneau/rest/client/RestResponseBody.java       | 10 +++--
 .../rest/mock/MockHttpClientConnectionManager.java | 13 +++++-
 .../apache/juneau/rest/mock/MockRestClient.java    |  7 +++-
 .../juneau/rest/mock/MockRestClientBuilder.java    |  6 +--
 14 files changed, 157 insertions(+), 37 deletions(-)

diff --git 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java
 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java
index 3611052..f50ca4c 100644
--- 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java
+++ 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/PropertyStoreTest.java
@@ -1564,6 +1564,7 @@ public class PropertyStoreTest {
        public void testSet() {
                PropertyStoreBuilder b = PropertyStore.create();
                b.set(OMap.of("A.foo", "bar"));
+               b.clear();
                b.set(OMap.of("A.baz", "qux"));
                b.add(null);
                assertObject(b.build()).json().is("{A:{baz:'qux'}}");
diff --git 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java
 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java
index 0f0ceac..920d4e3 100644
--- 
a/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java
+++ 
b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteMethodAnnotation_Test.java
@@ -23,7 +23,6 @@ import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Response;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
 import org.apache.juneau.rest.config.*;
 import org.apache.juneau.rest.mock.*;
 import org.junit.*;
@@ -238,7 +237,7 @@ public class Remote_RemoteMethodAnnotation_Test {
 
        @Test
        public void d01_returnTypes_partSerialization() throws Exception {
-               D1 x = client(D.class).openApi().build().getRemote(D1.class);
+               D1 x = 
MockRestClient.create(D.class).openApi().build().getRemote(D1.class);
                assertEquals("foo",x.postX1("foo"));
                
assertEquals("foo",IOUtils.read(x.postX2("foo").getEntity().getContent()));
                assertEquals("foo",IOUtils.read(x.postX3("foo")));
@@ -257,10 +256,6 @@ public class Remote_RemoteMethodAnnotation_Test {
        // Helper methods.
        
//------------------------------------------------------------------------------------------------------------------
 
-       private static RestClientBuilder client(Class<?> c) {
-               return MockRestClient.create(c).simpleJson();
-       }
-
        private static <T> T remote(Class<?> rest, Class<T> t) {
                return MockRestClient.build(rest).getRemote(t);
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
index f9218d9..6c1f025 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/PropertyStore.java
@@ -20,6 +20,7 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.PropertyStoreBuilder.*;
+import org.apache.juneau.assertions.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
@@ -565,6 +566,7 @@ public final class PropertyStore {
         * @return A new property instance.
         */
        public <T> T getInstanceProperty(String key, Object outer, Class<T> 
type, Object def, ResourceResolver resolver, Object...args) {
+               Assertions.assertArgNotNull("type", type);
                Property p = findProperty(key);
                if (p != null)
                        return p.asInstance(outer, type, resolver, args);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
index f18224e..71d751d 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
@@ -16,6 +16,7 @@ import java.io.*;
 import java.time.*;
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 
 /**
@@ -288,4 +289,19 @@ public class Assertions {
        public static StringAssertion assertReader(Reader r) throws IOException 
{
                return new StringAssertion(r == null ? null : IOUtils.read(r));
        }
+
+       /**
+        * Throws an {@link IllegalArgumentException} if the specified argument 
is <jk>null</jk>.
+        *
+        * @param <T> The argument data type.
+        * @param arg The argument name.
+        * @param o The object to check.
+        * @return The same argument.
+        * @throws IllegalArgumentException Constructed exception.
+        */
+       public static <T> T assertArgNotNull(String arg, T o) throws 
IllegalArgumentException {
+               if (o == null)
+                       throw new BasicIllegalArgumentException("Argument 
''{0}'' cannot be null", arg);
+               return o;
+       }
 }
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
index 94b32b6..0e77869 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_Context_Test.java
@@ -194,13 +194,15 @@ public class RestClient_Config_Context_Test {
 
        @Test
        public void a11_set() throws Exception {
-               client(null).set(
+               client(null)
+                       .add(
                                AMap.of(
                                        JSON_simpleMode,true,
                                        WSERIALIZER_quoteChar,"'",
                                        MOCKRESTCLIENT_restBean,A.class
                                )
-                       ).json().build().post("/echoBody",new 
A11()).run().assertBody().is("{foo:1}")
+                       )
+                       .json().build().post("/echoBody",new 
A11()).mediaType("text/json").run().assertBody().is("{foo:1}")
                ;
        }
 
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
index 719e56d..6cc813e 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Config_RestClient_Test.java
@@ -365,15 +365,23 @@ public class RestClient_Config_RestClient_Test {
 
        @Test
        public void a09_marshalls() throws Exception {
-               RestClient x = 
MockRestClient.create(A.class).marshalls(Xml.DEFAULT,Json.DEFAULT).build();
+               final RestClient x = 
MockRestClient.create(A.class).marshalls(Xml.DEFAULT,Json.DEFAULT).build();
 
-               x.post("/echoBody",bean).run().assertBody().is("{f:1}");
+               
assertThrown(()->x.post("/echoBody",bean).run()).contains("Content-Type not 
specified on request.  Cannot match correct serializer.  Use 
contentType(String) or mediaType(String) to specify transport language.");
+
+               
assertThrown(()->x.post("/echoBody",bean).contentType("text/json").run().getBody().as(ABean.class)).contains("Content-Type
 not specified in response header.  Cannot find appropriate parser.");
 
                ABean b = 
x.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
                assertObject(b).sameAs(bean);
 
+               b = 
x.post("/echoBody",bean).mediaType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
+               assertObject(b).sameAs(bean);
+
                b = 
x.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
                assertObject(b).sameAs(bean);
+
+               b = 
x.post("/echoBody",bean).mediaType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
+               assertObject(b).sameAs(bean);
        }
 
        @Test
@@ -395,19 +403,40 @@ public class RestClient_Config_RestClient_Test {
        @Test
        public void a11_serializers_parsers() throws Exception {
                @SuppressWarnings("unchecked")
-               RestClient x = 
MockRestClient.create(A.class).serializers(XmlSerializer.class,JsonSerializer.class).parsers(XmlParser.class,JsonParser.class).build();
+               final RestClient x = 
MockRestClient.create(A.class).serializers(XmlSerializer.class,JsonSerializer.class).parsers(XmlParser.class,JsonParser.class).build();
+
+               
assertThrown(()->x.post("/echoBody",bean).run()).contains("Content-Type not 
specified on request.  Cannot match correct serializer.  Use 
contentType(String) or mediaType(String) to specify transport language.");
+
+               
assertThrown(()->x.post("/echoBody",bean).contentType("text/json").run().getBody().as(ABean.class)).contains("Content-Type
 not specified in response header.  Cannot find appropriate parser.");
 
-               x.post("/echoBody",bean).run().assertBody().is("{f:1}");
                ABean b = 
x.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
                assertObject(b).sameAs(bean);
+
+               b = 
x.post("/echoBody",bean).mediaType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
+               assertObject(b).sameAs(bean);
+
                b = 
x.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
                assertObject(b).sameAs(bean);
 
-               x = 
MockRestClient.create(A.class).serializers(XmlSerializer.DEFAULT,JsonSerializer.DEFAULT).parsers(XmlParser.DEFAULT,JsonParser.DEFAULT).build();
-               x.post("/echoBody",bean).run().assertBody().is("{f:1}");
-               b = 
x.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
+               b = 
x.post("/echoBody",bean).mediaType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
                assertObject(b).sameAs(bean);
-               b = 
x.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
+
+               final RestClient x2 = 
MockRestClient.create(A.class).serializers(XmlSerializer.DEFAULT,JsonSerializer.DEFAULT).parsers(XmlParser.DEFAULT,JsonParser.DEFAULT).build();
+
+               
assertThrown(()->x2.post("/echoBody",bean).run()).contains("Content-Type not 
specified on request.  Cannot match correct serializer.  Use 
contentType(String) or mediaType(String) to specify transport language.");
+
+               
assertThrown(()->x2.post("/echoBody",bean).contentType("text/json").run().getBody().as(ABean.class)).contains("Content-Type
 not specified in response header.  Cannot find appropriate parser.");
+
+               b = 
x2.post("/echoBody",bean).accept("text/xml").contentType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
+               assertObject(b).sameAs(bean);
+
+               b = 
x2.post("/echoBody",bean).mediaType("text/xml").run().cacheBody().assertBody().is("<object><f>1</f></object>").getBody().as(ABean.class);
+               assertObject(b).sameAs(bean);
+
+               b = 
x2.post("/echoBody",bean).accept("text/json").contentType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
+               assertObject(b).sameAs(bean);
+
+               b = 
x2.post("/echoBody",bean).mediaType("text/json").run().cacheBody().assertBody().is("{\"f\":1}").getBody().as(ABean.class);
                assertObject(b).sameAs(bean);
        }
 
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
index 1d72279..6f15000 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Marshalls_Test.java
@@ -12,6 +12,7 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.client;
 
+import static org.apache.juneau.assertions.Assertions.*;
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
 
@@ -132,8 +133,7 @@ public class RestClient_Marshalls_Test {
                
x.post("/a01",bean).header("Accept","application/x-www-form-urlencoded").header("Content-Type","application/x-www-form-urlencoded").header("X-Accept","application/x-www-form-urlencoded").header("X-Content-Type","application/x-www-form-urlencoded").run().assertCode().is(200).getBody().as(Bean.class).check();
                
x.post("/a01",bean).header("Accept","text/openapi").header("Content-Type","text/openapi").header("X-Accept","text/openapi").header("X-Content-Type","text/openapi").run().assertCode().is(200).getBody().as(Bean.class).check();
 
-               // Bean will be serialized using toString().
-               
x.post("/a01",bean).header("X-Accept","nil").header("X-Content-Type","text/plain").run().assertCode().is(200).getBody().as(Bean.class).check();
+               
assertThrown(()->x.post("/a01",bean).run()).contains("Content-Type not 
specified on request.  Cannot match correct serializer.  Use 
contentType(String) or mediaType(String) to specify transport language.");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
@@ -152,8 +152,7 @@ public class RestClient_Marshalls_Test {
                
x.post("/a01",bean).header("Accept","application/x-www-form-urlencoded").header("Content-Type","application/x-www-form-urlencoded").header("X-Accept","application/x-www-form-urlencoded").header("X-Content-Type","application/x-www-form-urlencoded").run().assertCode().is(200).getBody().as(Bean.class).check();
                
x.post("/a01",bean).header("Accept","text/openapi").header("Content-Type","text/openapi").header("X-Accept","text/openapi").header("X-Content-Type","text/openapi").run().assertCode().is(200).getBody().as(Bean.class).check();
 
-               // Default.
-               
x.post("/a01",bean).header("X-Accept","nil").header("X-Content-Type","text/plain").run().assertCode().is(200).getBody().as(Bean.class).check();
+               
assertThrown(()->x.post("/a01",bean).run()).contains("Content-Type not 
specified on request.  Cannot match correct serializer.  Use 
contentType(String) or mediaType(String) to specify transport language.");
        }
 
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index ba6e170..dcf56d8 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -1093,6 +1093,31 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        public static final String RESTCLIENT_callHandler = PREFIX + 
"callHandler.o";
 
        /**
+        * Configuration property:  Connection manager
+        *
+        * <h5 class='section'>Property:</h5>
+        * <ul class='spaced-list'>
+        *      <li><b>ID:</b>  {@link 
org.apache.juneau.rest.client.RestClient#RESTCLIENT_connectionManager 
RESTCLIENT_connectionManager}
+        *      <li><b>Name:</b>  <js>"RestClient.connectionManager.o"</js>
+        *      <li><b>System property:</b>  <c>RestClient.connectionManager</c>
+        *      <li><b>Data type:</b>
+        *      <ul>
+        *              <li><b>Data type:</b>  {@link 
org.apache.http.conn.HttpClientConnectionManager}</c>
+        *      </ul>
+        *      <li><b>Default:</b>  Value returned by {@link 
org.apache.juneau.rest.client.RestClientBuilder#createConnectionManager()}
+        *      <li><b>Methods:</b>
+        *              <ul>
+        *                      <li class='jm'>{@link 
org.apache.juneau.rest.client.RestClientBuilder#connectionManager(HttpClientConnectionManager)}
+        *              </ul>
+        * </ul>
+        *
+        * <h5 class='section'>Description:</h5>
+        * <p>
+        * Allows you to override the connection manager used by the HTTP 
client.
+        */
+       public static final String RESTCLIENT_connectionManager = PREFIX + 
"connectionManager.o";
+
+       /**
         * Configuration property:  Console print stream.
         *
         * <h5 class='section'>Property:</h5>
@@ -1953,6 +1978,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        private final HeaderSupplier headers;
        private final NameValuePairSupplier query, formData;
        final CloseableHttpClient httpClient;
+       private final HttpClientConnectionManager connectionManager;
        private final boolean keepHttpClientOpen, leakDetection;
        private final UrlEncodingSerializer urlEncodingSerializer;  // Used for 
form posts only.
        private final HttpPartSerializer partSerializer;
@@ -2011,6 +2037,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        protected RestClient(PropertyStore ps) {
                super(ps);
                this.httpClient = getInstanceProperty(RESTCLIENT_httpClient, 
CloseableHttpClient.class);
+               this.connectionManager = 
getInstanceProperty(RESTCLIENT_connectionManager, 
HttpClientConnectionManager.class);
                this.keepHttpClientOpen = 
getBooleanProperty(RESTCLIENT_keepHttpClientOpen);
                this.errorCodes = getInstanceProperty(RESTCLIENT_errorCodes, 
Predicate.class, ERROR_CODES_DEFAULT);
                this.executorServiceShutdownOnClose = 
getBooleanProperty(RESTCLIENT_executorServiceShutdownOnClose);
@@ -3452,6 +3479,15 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
        }
 
        /**
+        * Returns the connection manager if one was specified in the client 
builder.
+        *
+        * @return The connection manager.  May be <jk>null</jk>.
+        */
+       public HttpClientConnectionManager getHttpClientConnectionManager() {
+               return connectionManager;
+       }
+
+       /**
         * Executes HTTP request using the default context.
         *
         * <ul class='notes'>
@@ -3709,7 +3745,11 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                return s;
                }
                List<Serializer> l = serializers.getSerializers();
-               return l.size() == 1 ? l.get(0) : null;
+               return (l.size() == 1 ? l.get(0) : null);
+       }
+
+       boolean hasSerializers() {
+               return ! serializers.getSerializers().isEmpty();
        }
 
        /*
@@ -3726,7 +3766,11 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                return p;
                }
                List<Parser> l = parsers.getParsers();
-               return l.size() == 1 ? l.get(0) : null;
+               return (l.size() == 1 ? l.get(0) : null);
+       }
+
+       boolean hasParsers() {
+               return ! parsers.getParsers().isEmpty();
        }
 
        @SuppressWarnings("unchecked")
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index 5474d94..fb4a1de 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -96,7 +96,6 @@ public class RestClientBuilder extends BeanContextBuilder {
 
        private HttpClientBuilder httpClientBuilder;
        private CloseableHttpClient httpClient;
-       private HttpClientConnectionManager httpClientConnectionManager;
        private boolean pooled;
 
        /**
@@ -799,11 +798,14 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         * @return The HTTP client to use.
         */
        protected CloseableHttpClient createHttpClient() {
+               Object cm = peek(RESTCLIENT_connectionManager);
                // Don't call createConnectionManager() if 
RestClient.setConnectionManager() was called.
-               if (httpClientConnectionManager == null)
+               if (cm == null)
                        
httpClientBuilder.setConnectionManager(createConnectionManager());
+               else if (cm instanceof HttpClientConnectionManager)
+                       
httpClientBuilder.setConnectionManager((HttpClientConnectionManager)cm);
                else
-                       
httpClientBuilder.setConnectionManager(httpClientConnectionManager);
+                       throw new RuntimeException("Invalid type for 
RESTCLIENT_connectionManager: " + cm.getClass().getName());
                return httpClientBuilder.build();
        }
 
@@ -5284,7 +5286,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder connectionManager(HttpClientConnectionManager 
connManager) {
-               this.httpClientConnectionManager = connManager;
+               set(RESTCLIENT_connectionManager, connManager);
                httpClientBuilder.setConnectionManager(connManager);
                return this;
        }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
index 73b01b2..c6bc151 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
@@ -2452,6 +2452,17 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        }
 
        /**
+        * Shortcut for setting the <c>Accept</c> and <c>Content-Type</c> 
headers on a request.
+        *
+        * @param value The new header values.
+        * @return This object (for method chaining).
+        * @throws RestCallException Invalid input.
+        */
+       public RestRequest mediaType(Object value) throws RestCallException {
+               return header("Accept", value).header("Content-Type", value);
+       }
+
+       /**
         * Sets the value for the <c>Content-Encoding</c> request header.
         *
         * <p>
@@ -2868,6 +2879,11 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                else if (serializer != null)
                                        entity = 
SerializedHttpEntity.of(input2, 
serializer).schema(requestBodySchema).contentType(contentType);
                                else {
+                                       if (client.hasSerializers()) {
+                                               if (contentType == null)
+                                                       throw new 
RestCallException(null, null, "Content-Type not specified on request.  Cannot 
match correct serializer.  Use contentType(String) or mediaType(String) to 
specify transport language.");
+                                               throw new 
RestCallException(null, null, "No matching serializer for media type ''{0}''", 
contentType);
+                                       }
                                        if (input2 == null)
                                                input2 = "";
                                        entity = new 
StringEntity(BeanContext.DEFAULT.getClassMetaForObject(input2).toString(input2),
 getRequestContentType(TEXT_PLAIN));
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java
index 8e97735..8162f55 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestResponseBody.java
@@ -816,10 +816,12 @@ public class RestResponseBody implements HttpEntity {
                        if (type.hasInputStreamMutater())
                                return 
type.getInputStreamMutater().mutate(asInputStream());
 
-                       throw new ParseException(
-                               "Unsupported media-type in request header 
''Content-Type'': ''{0}''",
-                               response.getStringHeader("Content-Type")
-                       );
+                       ct = response.getStringHeader("Content-Type");
+
+                       if (ct == null && client.hasParsers())
+                               throw new ParseException("Content-Type not 
specified in response header.  Cannot find appropriate parser.");
+
+                       throw new ParseException("Unsupported media-type in 
request header ''Content-Type'': ''{0}''", ct);
 
                } catch (ParseException | IOException e) {
                        response.close();
diff --git 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java
 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java
index c2b8781..0001fbb 100644
--- 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java
+++ 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockHttpClientConnectionManager.java
@@ -28,7 +28,7 @@ import org.apache.http.protocol.*;
  *
  * This implementation is NOT thread safe.
  */
-class MockHttpClientConnectionManager implements HttpClientConnectionManager {
+final class MockHttpClientConnectionManager implements 
HttpClientConnectionManager {
 
        private ConnectionRequest cr;
 
@@ -75,4 +75,15 @@ class MockHttpClientConnectionManager implements 
HttpClientConnectionManager {
 
        @Override /* HttpClientConnectionManager */
        public void shutdown() {}
+
+       @Override /* Object */
+       public int hashCode() {
+               return MockHttpClientConnectionManager.class.hashCode();
+       }
+
+       @Override /* Object */
+       public boolean equals(Object o) {
+               // All MockHttpClientConnectionManagers are considered equal.
+               return o != null && o instanceof 
MockHttpClientConnectionManager;
+       }
 }
diff --git 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
index 083687c..71df441 100644
--- 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
+++ 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
@@ -25,6 +25,7 @@ import javax.servlet.http.*;
 
 import org.apache.http.*;
 import org.apache.http.client.methods.*;
+import org.apache.http.conn.*;
 import org.apache.http.entity.*;
 import org.apache.http.message.*;
 import org.apache.juneau.*;
@@ -223,7 +224,6 @@ public class MockRestClient extends RestClient implements 
HttpClientConnection {
                MOCKRESTCLIENT_restBeanCtx = PREFIX + "restBeanCtx.o",
                MOCKRESTCLIENT_servletPath = PREFIX + "servletPath.s",
                MOCKRESTCLIENT_contextPath = PREFIX + "contextPath.s",
-               MOCKRESTCLIENT_mockHttpClientConnectionManager = PREFIX + 
"mockHttpClientConnectionManager.o",
                MOCKRESTCLIENT_pathVars = PREFIX + "pathVars.oms";
 
 
@@ -257,7 +257,10 @@ public class MockRestClient extends RestClient implements 
HttpClientConnection {
                this.contextPath = 
getStringProperty(MOCKRESTCLIENT_contextPath, "");
                this.servletPath = 
getStringProperty(MOCKRESTCLIENT_servletPath, "");
                this.pathVars = getMapProperty(MOCKRESTCLIENT_pathVars, 
String.class);
-               
getInstanceProperty(MOCKRESTCLIENT_mockHttpClientConnectionManager, 
MockHttpClientConnectionManager.class).init(this);
+
+               HttpClientConnectionManager ccm = 
getHttpClientConnectionManager();
+               if (ccm instanceof MockHttpClientConnectionManager)
+                       ((MockHttpClientConnectionManager)ccm).init(this);
        }
 
        private static PropertyStore preInit(PropertyStore ps) {
diff --git 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java
 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java
index 509d16a..fb7e308 100644
--- 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java
+++ 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClientBuilder.java
@@ -72,6 +72,7 @@ public class MockRestClientBuilder extends RestClientBuilder {
         */
        protected MockRestClientBuilder(PropertyStore ps) {
                super(ps);
+               connectionManager(new MockHttpClientConnectionManager());
        }
 
        /**
@@ -81,7 +82,7 @@ public class MockRestClientBuilder extends RestClientBuilder {
         * Provided so that this class can be easily subclassed.
         */
        protected MockRestClientBuilder() {
-               super(null);
+               this(null);
        }
 
        /**
@@ -214,9 +215,6 @@ public class MockRestClientBuilder extends 
RestClientBuilder {
 
        @Override /* ContextBuilder */
        public <T extends Context> T build(Class<T> c) {
-               MockHttpClientConnectionManager cm = new 
MockHttpClientConnectionManager();
-               set(MOCKRESTCLIENT_mockHttpClientConnectionManager, cm);
-               connectionManager(cm);
                return super.build(c);
        }
 

Reply via email to