我使用Robolectrics和Mockito来测试android项目,我模拟了一个使http请求后端的方法。
http客户端的实际类:
public class MyHttpClient {
...
public int sendDataToBackend(Object data) {
return doHttpRequest(data);
}
private int doHttpRequest() {
System.out.println("start http request ...");
...
return responseCode;
}
}
以上MyHttpClient
类用于MyService
类:
public class MyService {
...
public void notifyBackend(Object data) {
MyHttpClient client = new MyHttpClient();
int responseCode = client.sendDataToBackend(data);
...
}
}
我单元测试MyService
:
@RunWith(RobolectricTestRunner.class)
public class MyServiceTest {
@Mock
private MyHttpClient client;
@InjectMocks
private MyService service;
@Before
public void setUp() {
client = new MyHttpClient();
service = new MyService();
}
@Test
public void testNotifyBackend() {
Object data = generateData();
//stub method call
when(client.sendDataToBackend(data)).thenReturn(200);
service.notifyBackend(data);
}
}
我运行上面的单元测试,我预计sendDataToBackend()
类中的MyHttpClient
函数体不会被执行,因为我们已经模拟/存根函数返回200,但是我仍然看到System.out.print()
消息:
start http request ...
来自MyHttpClient#doHttpRequest()
,为什么?
(我的测试失败了,因为它试图做真正的http请求)
======更新=======
此外,我还认为我不应该在client = new MyHttpClient
中setUp()
,因为client
应该被嘲笑,但是当我尝试时:
@Before
public void setUp() {
service = new MyService();
}
我在中获得了 NullPointerException
when(client.sendDataToBackend(data)).thenReturn(200);
,
这就是我在client = new MyHttpClient
中添加setUp()
的原因。我还想问一下为什么我得到 NullPointerException ,如果client
被模拟了?
答案 0 :(得分:2)
不是在服务中创建客户端,而是通过构造函数提供它:
class MyService {
final MyHttpClient client;
MyService(MyHttpClient client) { this.client = client; }
}
然后,在您的测试中,将模拟客户端提供给它。它就这么简单。
@RunWith(MockitoJunitRunner.class)
public class MyServiceTest {
@Mock
private MyHttpClient client;
private MyService service;
@Before
public void setUp() {
service = new MyService(client);
}
....
}
答案 1 :(得分:0)
将您的方法更改为:
@Before
public void setUp() {
service = new MyService();
}
你嘲笑它,对。但是,您通过为client
分配MyHttpClient
新实例来覆盖该实例。