我有一个存根JSON OBJECT,但需要使用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());
我创建了以下Mocks:
@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?
有任何建议吗?
由于
答案 0 :(得分:6)
你可能必须模仿HttpClient
和HttpResponse
,如果它们是接口(虽然,根据您的库,您可以使用MockHttpClient
或{ {1}}),但不应嘲笑其他任何内容。
为什么?
模拟是在我们无法具体化的类上建立预期的输出行为,或者更确切地说,我们想要以特定方式为该特定测试实例行为的类。您希望确保从模拟MockHttpResponse
获得正确的响应,并且在调用HttpClient
时,它会返回有意义的response.getEntity()
。你可以选择嘲笑或不嘲笑;我个人不会,因为模拟不添加任何额外的值(除了可能验证特定方法被调用)。
其他所有内容都是具体实现 - 您应该允许其他对象与之前模拟的元素的结果进行交互,以确保它们的行为与没有模拟时一样。
实际上......你真的不能嘲笑那些,除非你传递它们或以某种方式注入它们。我会 强烈 阻止您尝试模拟该方法中的任何HttpEntity
ed对象。
你没有指明你所声称的内容,但我希望它在某种程度上是你的new
。我断言你希望放入它的内容实际上是将它放入JSON对象中,并且还验证你的模拟对象是按照你期望的方式调用和调用的。
顺便说一句,您的注释JSONObject
没有级联 - 您必须使用@Mock
注释所有模拟字段,然后使用@Mock
注释测试类,或使用{{1 (一个或另一个;除边缘情况外,两者都不是必需的)。如果选择注释,请不要忘记测试对象上的@RunWith(MockitoJunitRunner.class)
。
最后,你的MockitoAnnotation.initMocks(this)
条件符合我的预期 - 那些应该没问题。
答案 1 :(得分:2)
是的,你可能需要你提到的所有时间陈述。
但是,您可以返回mockInputStream
new ByteArrayInputStream( "{foo : 'bar'}".getBytes() )
最后,您可以验证json响应对象是否具有值为'bar'的'foo'属性。
那就是说,我不确定给定的方法是否值得测试 - 因为它只会打开流并读取数据。
答案 2 :(得分:0)
首先了解Mocking
的含义。
1)为什么我们需要嘲笑?
假设我们不想调用任何原始方法,并且希望我们不应该使用原始方法调用虚方法,那么我们应该去模拟。
例如:
Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse)
这意味着无论何时调用此execute()
,您都会返回自己准备的值而非原始mockHttpResponse
。
因此,在您的情况下准备您的存根对象并在需要时进行模拟。 在这里你准备你的回答(注意实际但是假的)。
mockHttpResponse.setEntity(new Entity());
mockHttpResponse.getEntity().setContent('{yourJsonString}');
所以每当你的
mockHttpClient.execute(mockHttpPost); //will be called
然后它将返回您在测试方法中手动准备的响应。
当你的控制权来到
时 new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
然后,当调用{yourJsonString}
时,您将获得response.getEntity().getContent()
,并让其余代码执行其功能。最后,您的JSON存根对象将被准备好。
记住测试用例仅供开发人员使用。我们可以模拟任何东西并返回任何东西或任何存根对象。我们编写测试用例来通过传递预期值和非预期值来检查我们的控制流。
这将使您的工作变得轻松。现在您想要模拟您的BufferReader类使用它。
BufferedReader bufferedReader = org.mockito.Mockito.mock(BufferedReader.class);
when(bufferedReader.readLine()).thenReturn("first line").thenReturn("second line");
org.junit.Assert.when(new Client(bufferedReader).parseLine()).thenEquals(IsEqual.equalTo("1"));