使用Mockito模拟发布请求会引发javax

使用Mockito模拟发布请求会引发javax

本文介绍了使用Mockito模拟发布请求会引发javax.ws.rs.ProcessingException:RESTEASY004655:无法调用请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Mockito完全陌生,我需要模拟一个发布请求,以便我可以单独测试一个客户端.但是,无论我做什么我都会得到RESTEASY004655: Unable to invoke request异常.这是到目前为止的简化版本.我有TestClassA类,它向api发送发布请求,如下所示:

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.

推荐答案

由于您嘲笑了ResteasyWebTarget并且未定义request()方法的返回值,所以出现了该异常.

Because you mocked ResteasyWebTarget and didn't define what should be the return of request() method, you got that exception.

您应该首先模拟请求并将其返回到request()方法,然后从mockedRequest

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()文档

Invocation.Builder文档

这篇关于使用Mockito模拟发布请求会引发javax.ws.rs.ProcessingException:RESTEASY004655:无法调用请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 07:02