我是Mockito的初学者。我有一个要模拟的HTTP get调用。
必须测试的实用程序文件是这个。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class GoogleAccessor {
private HttpClient client ;
public void getGoogle() throws ClientProtocolException, IOException {
String url = "http://www.google.com/search?q=httpClient";
client = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
try {
HttpResponse response = client.execute(request);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result);
} catch (Exception e) {
System.out.println(e);
}
}
}
这是我的jUnit测试
import static org.mockito.Mockito.when;
import org.apache.http.ProtocolVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import org.mockito.Mock;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
public class TestTest {
@Mock
private HttpClient mClient;
@InjectMocks
private GoogleAccessor dummy;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testAddCustomer_returnsNewCustomer() throws Exception {
when(mClient.execute(Mockito.any())).thenReturn(buildResponse(201, "OK", "{\"message\":\"Model was stored\"}"));
dummy.getGoogle();
}
BasicHttpResponse buildResponse(int statusCode, String reason, String body) {
BasicHttpResponse response = new BasicHttpResponse(
new BasicStatusLine(new ProtocolVersion("HTTP", 1, 0), statusCode, reason));
if (body != null) {
response.setEntity(new ByteArrayEntity(body.getBytes()));
}
return response;
}
}
因为,没有启动mclient,我一直收到此错误
java.lang.NullPointerException
at com.amazon.cartographertests.accessors.TestTest.testAddCustomer_returnsNewCustomer(TestTest.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
...
UPDATE1:我已合并@glytching的注释并删除了setup()中的变量初始化我已经合并了@Maciej Kowalski的评论,并使客户端成为Utility类中的类变量
更新2:
解决了正确的导入后,NPE错误已解决-> import org.mockito.Mock;
但是,仍然没有看到模拟响应的问题
您在此处将mClient
声明为模拟对象:
@Mock
private HttpClient mClient;
但是您还要在DefaultHttpClient
中为其分配一个setUp()
的具体实例:
mClient = new DefaultHttpClient();
只需从setup()
中删除该行,测试中使用的mClient
实例将是一个模拟。
更新:您更新的问题显示此导入:
import org.easymock.Mock;
应该是
import org.mockito.Mock;
[此指令:MockitoAnnotations.initMocks(this);
将初始化带有org.mockito.Mock
注释的任何类成员,它不会对带有org.easymock.Mock
注释的类成员做任何事情,因此我怀疑mClient
尚未初始化,因此是NPE。当我以正确的导入在本地运行代码时,测试成功完成,没有例外。
注意:GoogleAccessor
内还有一个问题,您在此处HttpClient
内明确实例化了getGoogle
...
HttpClient client = new DefaultHttpClient();
...因此此方法将永远不会使用模拟的HttpClient
。
如果您注释掉此行:
HttpClient client = new DefaultHttpClient();
...并将该类成员添加到GoogleAccessor
:
private HttpClient client;
...然后,您会发现模拟的客户端将在getGoogle()
中使用。
用于背景;为了在类中使用模拟的实例,您必须提供某种方式让测试运行程序将该模拟的实例inject插入类。在您的测试用例中,您正在使用@InjectMocks
,因此您指示测试运行器将您的模拟程序注入GoogleAccessor
,但是由于没有该类型的类成员,因此测试运行器没有任何东西可以分配模拟程序to。另外,即使它可以将模拟物分配给某些内容,您也可以声明http客户端inside getGoogle()
,从而强制该方法的所有调用都使用DefaultHttpClient
的具体实例。
您正在方法本身中创建客户端。除非您创建包级方法,否则您无法模拟它:
HttpClient getNewClient(){
return new DefaultHttpClient();
}
并在方法中使用它。
public void getGoogle() throws ClientProtocolException, IOException {
String url = "http://www.google.com/search?q=httpClient";
HttpClient client = getNewClient();
然后,您需要监视被测类以使该方法保持原样并模拟getNewClient
方法以返回您想要的内容:
@Mock
private HttpClient mClient;
@InjectMocks
@Spy
private GoogleAccessor dummy;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void testAddCustomer_returnsNewCustomer() throws Exception {
doReturn(null).when(mClient).execute(Mockito.any()));
dummy.getGoogle();
}
与间谍打交道时,您还需要使用doReturn().when()
语法而不是when().then()
。