Java 使用 Mockito 和 Junit 模拟 Jersey 客户端请求响应
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21205853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mock Jersey Client Request response using Mockito and Junit
提问by kunal
I searched on the forum and tried to get some heads up, by experimenting what others have already mentioned in other related posts but nothing worked for me since I am new to mockito junit, hence posting this question.
我在论坛上搜索并试图通过试验其他人在其他相关帖子中已经提到的内容来提神醒脑,但由于我是 mockito junit 的新手,因此对我没有任何帮助,因此发布了这个问题。
I have a rest client , which calls Rest webservice :-
我有一个 rest 客户端,它调用 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;
}
}
My plan is to unit test getProcessString(String url) method. My RestClientUnitTest.java code is shown below:-
我的计划是对 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;*/
}
}
However my unit test is failing at :- doReturn(webResource).when(mockClient).resource(URL); error trace is :-
但是我的单元测试失败了:- doReturn(webResource).when(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.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.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access 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");
0(ParentRunner.java:42)
at org.junit.runners.ParentRunner.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)
Not sure what am I missing here? Any ideas and suggestions will be appreciated
不确定我在这里错过了什么?任何想法和建议将不胜感激
After some analysis, tweaked the code in setUp() method as :-
经过一些分析,将 setUp() 方法中的代码调整为:-
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.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)
So no more getting the earlier exception, but now it seems trying to actually connect at the URL for webResource.get() and hence giving below error:-
所以不再得到早期的异常,但现在它似乎试图实际连接 webResource.get() 的 URL,因此给出以下错误:-
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
采纳答案by Andy
To your 1st error log: it tells you how you should use the API:
对于您的第一个错误日志:它告诉您应该如何使用 API:
//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());
To your second error: you call Client mockClient = Client.create();
which is NOT mocking, but calling a real method.
你的第二个错误:你调用Client mockClient = Client.create();
这不是嘲笑,而是调用一个真正的方法。
This is how you should do it:
你应该这样做:
##代码##However, you are mocking Jersey's Client
but you do not set that mocked instance to your RestClient
, and therefore it is using the real one. Either you introduce a setter to RestClient
which sets the Client
instance (which is not very nice), or you get more sophisticated and mock Client.create()
, which is a static method and Mockitois not able to mock static methods. Instead you can take a look at PowerMock(which uses Mockito; it still has some limitations) or JMockit(which is a complete and mighty mocking-framework, but documentation is quite short)
但是,您正在嘲笑 Jersey,Client
但您没有将该模拟实例设置为您的RestClient
,因此它使用的是真实的。要么引入一个 setter 来RestClient
设置Client
实例(这不是很好),要么变得更加复杂和 mock Client.create()
,这是一个静态方法,而Mockito无法模拟静态方法。相反,您可以查看PowerMock(使用 Mockito;它仍然有一些限制)或JMockit(这是一个完整而强大的模拟框架,但文档很短)