模拟泽西客户请求使用Mockito和Junit的回复

时间:2014-01-18 15:08:13

标签: java junit mockito jersey-client

我在论坛上搜索并试图通过试验其他人在其他相关帖子中已经提到过的内容,但是因为我是mockito junit的新手,所以没有任何对我有用,因此发布了这个问题。

我有一个休息客户端,它调用Rest webservice: -

// Rest Client code
public static String getProcessString(String url) {
Client client = Client.create();
com.sun.jersey.api.client.WebResource webResource = client.resource(url);
webResource.accept("application/json");
/*if (response.getStatus() != 200) {
       throw new RuntimeException("Failed : HTTP error code : "
        + response.getStatus());
    }*/
String process = webResource.get(String.class);

return process;

}

我的计划是单元测试getProcessString(String url)方法。我的RestClientUnitTest.java代码如下所示: -

package......service.workflow.client;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.doReturn;
import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
@RunWith(MockitoJUnitRunner.class)
public class RestClientUnitTest {
    @InjectMocks
    private  RestClient  RestClient = new  RestClient();

    @Mock
    private com.sun.jersey.api.client.WebResource res;





    @Mock
    private Client client;

    private String URL = "http://localhost:9095/jersey/recoveryservice/fetchUpdateProcesses?oldProcessDefinitionId=maker_checker&newProcessDefinitionId=maker_checker_v1";
    @Before
    public void setUp() throws Exception {
        Client mockClient = Client.create();
        doReturn(mockClient).when(client).create();
        //WebResource webResource = mockClient.resource(URL);
        doReturn(webResource).when(mockClient).resource(URL);
        //when(mockClient.resource(URL)).thenReturn(res);
        doReturn("OK").when(res).get((Class<String>) any());
        //when(webResource.get((Class<String>) any())).thenReturn("OK");

    }

    @Test
    public void testgetProcessString() {
        Assert.assertEquals(RestClient.getProcessString("http://localhost:9095/jersey/recoveryservice/fetchUpdateProcesses?oldProcessDefinitionId=maker_checker&newProcessDefinitionId=maker_checker_v1"), "OK");
        /*Client client = Client.create();
        com.sun.jersey.api.client.WebResource webResource = client.resource(url);
        webResource.accept("application/json");
        if (response.getStatus() != 200) {
               throw new RuntimeException("Failed : HTTP error code : "
                + response.getStatus());
            }
        String process = webResource.get(String.class);

        return process;*/
    }

}

但是我的单元测试失败了: -     doReturn(webResource)。当(mockClient).resource(URL); 错误跟踪是: -

 org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
-> at .......service.workflow.client.RestClientUnitTest.setUp(RestClientUnitTest.java:35)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. although stubbed methods may return mocks, you cannot inline mock creation (mock()) call inside a thenReturn method (see issue 53)

    at ......service.workflow.client.RestClientUnitTest.setUp(RestClientUnitTest.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

不确定我在这里缺少什么?任何想法和建议将不胜感激

经过一些分析后,将setUp()方法中的代码调整为: -

    Client mockClient =Client.create();
    //WebResource mockWebResource = Mockito.mock(WebResource.class);
    //when(client.create()).thenReturn(mockClient);
    doReturn(mockClient).when(client).create();
     res = mockClient.resource(URL);

    when(res.get((Class<String>) any())).thenReturn("OK"); ---> Error
    //stub(res.get((Class<String>) any())).toReturn("OK");

所以不再获得早期的异常,但现在它似乎试图在webResource.get()的URL处实际连接,从而给出以下错误: -

  com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused: connect
    at com.sun.jersey.client.urlconnection.URLConnectionClientHandler.handle(URLConnectionClientHandler.java:148)
    at com.sun.jersey.api.client.Client.handle(Client.java:642)
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:601)
    at com.sun.jersey.api.client.WebResource.get(WebResource.java:187)
    at ........service.workflow.client.RestClientUnitTest.setUp(RestClientUnitTest.java:52)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)

1 个答案:

答案 0 :(得分:1)

到第一个错误日志:它告诉您应该如何使用API​​:

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);

你的第二个错误:你打电话给Client mockClient = Client.create();这不是嘲笑,而是打电话给真正的方法。

这是你应该怎么做的:

//First you create a mock with an annotation
@Mock
private Client clientMock;

// ...

// Then you define special behaviour, e.g.
when(clientMock.foo()).thenReturn("bar");

// Then you use the mock instance:
assertEquals("bar", clientMock.foo());

但是,你在嘲笑泽西岛的Client,但是你没有将那个模拟的实例设置为你的RestClient,因此它正在使用真实的实例。你要么设置一个setter到RestClient设置Client实例(这不是很好),或者你得到更复杂的模拟Client.create(),这是一个静态方法和{{3 }}。相反,您可以查看 Mockito is not able to mock static methods (使用Mockito;它仍然有一些限制)或 PowerMock (这是一个完整而强大的模拟框架,但文档很短)