问题
I'm totally new to Mockito and I need to mock a post request so that I can test a client alone. However, no matter what I do I get the RESTEASY004655: Unable to invoke request
exception. This is the simplified version of what I have so far. I have the class TestClassA which sends a post request to an api as follows:
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.Response;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestClassA {
public int moveActual(String path) throws IOException {
Response resp = null;
String newHome = "0" ;
ResteasyClient client = new ResteasyClientBuilder().build();
ResteasyWebTarget callTarget = client.target(path) ;
Map<String, Object> request = new HashMap<>();
request.put("operation", "dislocation");
request.put("direction", "right");
request.put("amount", "2");
request.put("unit", "metric");
String payload = new ObjectMapper().writeValueAsString(request);
resp = callTarget.request().post(Entity.entity(payload, "application/json"));
String outcome = resp.readEntity(String.class);
ObjectMapper outcomeMapper = new ObjectMapper();
@SuppressWarnings("unchecked")
Map<String, Object> finalResponse = (Map<String, Object>) outcomeMapper.readValue(outcome, Map.class);
if (finalResponse != null) {
newHome = (String) finalResponse.get("coordinate");
}
return Integer.parseInt(newHome) ;
}
}
I try to mock the post request using the mockito test bellow:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.BDDMockito.given;
import java.util.HashMap;
import java.util.Map;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import externalTests.TestClassA;
@RunWith(MockitoJUnitRunner.class)
public class DispositionMockTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
ResteasyWebTarget targetMock;
@InjectMocks
TestClassA classA;
@Test
public void dispositionTest() throws Exception {
// Given
Map<String, Integer> outcomeMap = new HashMap<String, Integer>() ;
outcomeMap.put("coordinate", 4) ;
Response resp = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(outcomeMap).build() ;
// Builder req = DispositionMockTest.fakeRequest() ;
// given(req.post(ArgumentMatchers.any(Entity.class))).willReturn(fakeRequest()) ;
given(targetMock.request().post(ArgumentMatchers.any(Entity.class))).willReturn(resp) ;
// When
int result = classA.moveActual("url to what has to run") ;
// Then
assertEquals(4, result);
}
}
I also tried to mock the request method using the two commented out lines in the test and have it return more or less fake Builder from the method bellow.
public static Builder fakeRequest() {
ResteasyClient httpClient = new ResteasyClientBuilder().build();
ResteasyWebTarget target = httpClient.target("");
Builder req = target.request() ;
return req ;
}
But I keep getting this exception.
javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: org.apache.http.client.ClientProtocolException
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:325)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:443)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:62)
at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.post(ClientInvocationBuilder.java:219)
at externalTests.TestClassA.moveActual(TestClassA.java:33)
at externalTests.DispositionMockTest.dispositionTest(DispositionMockTest.java:60)
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.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:46)
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.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:77)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:83)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
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)
Caused by: org.apache.http.client.ClientProtocolException
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:187)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:320)
... 33 more
Caused by: org.apache.http.ProtocolException: Target host is not specified
at org.apache.http.impl.conn.DefaultRoutePlanner.determineRoute(DefaultRoutePlanner.java:71)
at org.apache.http.impl.client.InternalHttpClient.determineRoute(InternalHttpClient.java:125)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
... 36 more
I tried many possible solutions I found online but I can't get anything to work. If anyone knows how I can mock a post request I would be truly thankful to learn from them.
回答1:
Because you mocked ResteasyWebTarget
and didn't define what should be the return of request()
method, you got that exception.
You should first mock request and return it to the request()
method and define the behavior to post()
method from mockedRequest
@Mock
private Invocation.Builder mockedRequest;
@Test
public void dispositionTest() throws Exception {
when(targetMock.request()).thenReturn(mockedRequest);
when(mockedRequest.post(any(Entity.class))).thenReturn(resp) ;
}
WebTarget request() doc
Invocation.Builder doc
来源:https://stackoverflow.com/questions/62158437/mocking-a-post-request-using-mockito-raises-javax-ws-rs-processingexception-res