Mocking a post request using Mockito raises javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request

邮差的信 提交于 2020-06-29 04:14:30

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!