java使用Mockito for HTTP客户端
我有一个存根JSON对象,但需要使用Mockito模拟以下内容:
HttpResponse response = defaultHttpClient.execute(postRequest);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuilder result = new StringBuilder();
while ((line = rd.readLine()) != null) {
result.append(line);
}
JSONObject jsonResponseObject = new JSONObject(result.toString());
我创建了以下模拟:
@Mock
private HttpClient mockHttpClient;
private HttpPost mockHttpPost;
private HttpResponse mockHttpResponse;
private HttpEntity mockHttpEntity;
private InputStream mockInputStream;
private InputStreamReader mockInputStreamReader;
private BufferedReader mockBufferedReader;
并具有以下when
语句:
Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse);
Mockito.when(mockHttpResponse.getEntity()).thenReturn(mockHttpEntity);
Mockito.when(mockHttpEntity.getContent()).thenReturn(mockInputStream);
问:我需要创建所有这些“when”语句吗?如果需要,那么需要创建哪些其他语句才能访问存根JSON
有什么建议吗
谢谢
# 1 楼答案
是的,你可能需要你提到的所有when语句。 但是,您可以直接返回
new ByteArrayInputStream( "{foo : 'bar'}".getBytes() )
,而不是返回mockInputStream
最后,您可以验证json响应对象是否具有值为“bar”的“foo”属性
尽管如此,我不确定给定的方法是否值得测试——因为它所做的一切都是打开流和读取数据
# 2 楼答案
首先理解
Mocking
的含义1)为什么我们需要嘲笑
假设我们不想调用任何原始方法,并且希望我们应该调用一个虚拟方法,而不是原始方法,那么我们应该进行模拟
例如:
这意味着无论何时调用
execute()
,您都将返回自己准备好的值,而不是原始的mockHttpResponse
因此,在您的情况下,准备存根对象,如果需要,可以进行模拟。 在这里,你准备好你的回答(注意实际的,但不真实)
所以当你的
然后它将返回您在测试方法中手动准备的响应
当你的控制权到了
然后,当调用
response.getEntity().getContent()
时,您将得到{yourJsonString}
,并让rest代码完成其功能。最后,JSON存根对象将准备就绪请记住,测试用例只是为开发人员提供帮助。我们可以模拟任何东西并返回任何东西或任何存根对象。我们只需编写测试用例,通过传递预期值和非预期值来检查控制流
这将使你的工作变得容易。现在你想用这个来模拟你的BufferReader类
# 3 楼答案
如果
HttpClient
和HttpResponse
是接口的话,可能需要模拟HttpClient
和HttpResponse
(不过,根据库的不同,可以使用MockHttpClient
或MockHttpResponse
),但你不应该模拟其他任何东西为什么
模拟是在我们无法具体化的类上建立预期的输出行为,或者更确切地说,在这个特定的测试实例中,我们希望以某种方式表现的类。您希望确保从模拟
HttpClient
返回正确的响应,并且在调用response.getEntity()
时,它会返回有意义的HttpEntity
。你可以选择嘲弄,也可以不嘲弄;我个人不会,因为mock没有添加任何额外的值(除了验证是否调用了特定的方法)其他一切都是一个具体的实现——您应该允许其他对象与之前模拟的元素的结果进行交互,以确保它们的行为与没有模拟时的行为相同
实际上。。。你真的不能嘲笑它们,除非你把它们传进来或以某种方式注射进去。我会极力劝阻你不要用那种方法模拟任何
new
的对象你没有具体说明你在断言什么,但我希望这是你在某种程度上的
JSONObject
。我会断言,您希望放入其中的内容实际上会进入JSON对象,并验证您的模拟对象是否以您期望的方式被调用和调用顺便说一句,您的注释
@Mock
不是层叠的——您必须用@Mock
注释所有模拟字段,然后用@RunWith(MockitoJunitRunner.class)
注释测试类,或者使用MockitoAnnotation.initMocks(this)
(一个或另一个;除边缘情况外,这两个都不是必需的)。如果选择注释,不要忘记测试对象上的@InjectMocks
最后,你的
when
条件做了我希望他们做的事情——这些应该没问题