Java 对HTTP客户端使用Mockito

Java 对HTTP客户端使用Mockito,java,json,mocking,mockito,Java,Json,Mocking,Mockito,我有一个存根JSON对象,但需要使用Mockito模拟以下内容: HttpResponse response = defaultHttpClient.execute(postRequest); BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); StringBuilder result = new StringBuilder(); while ((lin

我有一个存根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()); 
我创建了以下模拟:

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;
并且在语句时具有以下

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()); 
    Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse); 
    Mockito.when(mockHttpResponse.getEntity()).thenReturn(mockHttpEntity);
    Mockito.when(mockHttpEntity.getContent()).thenReturn(mockInputStream);
问:我需要创建所有这些“when”语句吗?如果需要,那么需要创建哪些其他语句才能访问存根JSON

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()); 
有什么建议吗

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()); 

谢谢

是的,您可能需要您提到的所有when语句。
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()); 
但是,您可以只返回
newbytearrayinputstream(“{foo:'bar'}.getBytes()”)

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()); 
最后,您可以验证json响应对象是否具有值为“bar”的“foo”属性

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()); 

也就是说,我不确定给定的方法是否值得测试,因为它所做的一切都是打开流和读取数据。

首先理解
模拟的含义

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()); 
1) 为什么我们需要嘲笑

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()); 
假设我们不想调用任何原始方法,并且希望调用一个虚拟方法而不是原始方法,那么我们应该进行模拟

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()); 
例如:

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()); 
Mockito.when(mockHttpClient.execute(mockHttpPost)).thenReturn(mockHttpResponse)
这意味着无论何时调用此
execute()
,您都将返回自己准备好的值,而不是原始的
mockHttpResponse

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()); 
因此,在您的情况下,准备存根对象并在需要时模拟它。 在这里,您准备好了您的回答(注意实际的,但不真实)

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()); 
所以当你的

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()); 
  mockHttpClient.execute(mockHttpPost); //will be called
然后它将返回您在测试方法中手动准备的响应

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()); 
当你的控制权到了

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()); 
  new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
然后,当调用
response.getEntity().getContent()
时,您将获得
{yourJsonString}
,并让rest代码执行其功能。最后,将准备好JSON存根对象

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()); 
请记住,测试用例只是为开发人员提供帮助。我们可以模拟任何内容并返回任何内容或任何存根对象。我们只需编写测试用例,通过传递预期值和非预期值来检查控制流

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()); 
这将使您的工作变得简单。现在您要模拟您的BufferReader类,请使用此选项

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()); 
 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"));
如果它们是接口,您可能必须模拟
HttpClient
HttpResponse
(尽管根据您的库,您可以使用
MockHttpClient
MockHttpResponse
),但您不应该模拟任何其他内容

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()); 
为什么?

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()); 
模拟是在我们无法具体化的类上建立预期的输出行为,或者更确切地说,是在我们希望以某种方式对这个特定的测试实例进行操作的类上建立预期的输出行为。您希望确保从模拟的
HttpClient
返回正确的响应,并且在调用
response.getEntity()
时,它会返回有意义的
HttpEntity
。你可以选择嘲弄,也可以不嘲弄;我个人不会,因为mock没有添加任何额外的值(除了验证是否调用了特定的方法)

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()); 
其他一切都是一个具体的实现——您应该允许其他对象与之前模拟的元素的结果交互,以确保它们的行为与没有模拟时的行为相同

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()); 
事实上,你真的不能嘲笑他们,除非你把他们传进来或者以某种方式注射进去。我强烈地不鼓励您尝试用该方法模拟任何新的
ed对象

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()); 
您没有指定要断言的内容,但我希望它是您的
JSONObject
。我要断言,您希望放入其中的内容实际上已放入JSON对象中,并且还要验证您的模拟对象是否以您期望的方式被调用和调用

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
不是层叠的-您必须用
@Mock
注释所有模拟字段,然后要么用
@RunWith(MockitoJunitRunner.class)
注释测试类,要么使用
MockitoAnnotation.initmock(this)
(一个或另一个;除边缘情况外,这两个都不是必需的)。如果选择注释,请不要忘记测试对象上的
@injectmock

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()); 

最后,当你的
条件达到我期望的效果时,你的
应该没问题。

请再添加一些代码,以便我们能够理解确切的模拟对象你是否使用Spring MVC之类的web框架?嗨,谢谢你的澄清!!不确定这里需要做什么,但我正试图避免进行实际的HttpClient调用,因为我已经处理(解析)了来自该调用的响应的最终版本,这是一个我已经存根的JSON对象。请告知。。谢谢这很有帮助。但正如我在问题中提到的,当调用HttpResponse response=defaultHttpClient.execute(postRequest)时,我返回一个mockHttpResponse。但是在实际的方法中,在返回JSON对象之前,我必须执行3个步骤。因此,如果在运行response.getEntity().getContent()时返回存根JSON对象,那么在运行原始方法中的后续语句时,这不是一个问题吗?请建议..点击这个链接了解更多细节。我只是解释你想要模仿,何时模仿rest取决于你的视角。
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());