:)
我在使用Volley模拟网络异常时遇到问题。我的想法是“模拟”将始终引发异常的Network类。然后在我的RequestQueue中使用该网络,并测试在引发网络异常时我的DataManager(MyManager)的行为。我知道这种方法可能并不完全正确,但是我希望我可以知道一种更好的方法来实现我的UnitTest案例。
顺便说一下,我使用Robolectric 2.2和Mockito 1.9.5。让我们深入研究代码:
RequestQueue mMainRequestQueue;
private Network mMockedNetwork;
@Before
public void setup(){
Robolectric.getFakeHttpLayer().interceptHttpRequests(false);
ShadowLog.stream = System.out;
mMockedNetwork = spy(new BasicNetwork(new HurlStack()));
mMainRequestQueue = new RequestQueue(new NoCache(), mMockedNetwork);
mMainRequestQueue.start();
}
@Test
public void testLogin() throws Exception {
doThrow(new VolleyError()).when(mMockedNetwork).performRequest(any(JsonObjectRequest.class));
MyManager.getInstance(Robolectric.application.getApplicationContext()).setMainQueue(mMainRequestQueue);
MyManager.getInstance(Robolectric.application.getApplicationContext()).createSession("sessionId", "date", new MyManager.OnResponseReceivedListener() {
@Override
public void responseReceived(boolean error, Object responseObject) {
if (error) {
...
} else {
...
}
}
});
}
MyManager
createSession(..)
方法仅创建JsonObjectRequest
的新实例,并在收到响应时调用OnResponseReceivedListener
的方法。当我运行测试时,永远不会调用回调方法(JSONObjectRequest中的方法,当然还有侦听器中的方法)。
知道为什么吗?我想念什么吗?也许整个方法是错误的?
非常感谢大家!
编辑
我也尝试用此
new RequestQueue(...)
替换mMainRequestQueue = new RequestQueue(new NoCache(), mMockedNetwork, 4,new ExecutorDelivery(Executors.newSingleThreadExecutor()));
行结果相同。
编辑2
正如David Wallace所提到的那样,该方法是从Volley库类(称为NetworkDispatcher Here is the link)中调用的
....
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
TrafficStats.setThreadStatsTag(request.getTrafficStatsTag());
}
// Perform the network request.
NetworkResponse networkResponse = mNetwork.performRequest(request);
request.addMarker("network-http-complete");
// If the server returned 304 AND we delivered a response already,
// we're done -- don't deliver a second identical response.
if (networkResponse.notModified && request.hasHadResponseDelivered()) {
request.finish("not-modified");
continue;
}
...
使用“模拟”对象作为参数在requestQueue中创建networkDispatchers。因此,我希望可以调用该方法。
最佳答案
在您的@Before
方法中,启动RequestQueue
线程,该线程又调用performRequest
。稍后,在您的@Test
方法中,对performRequest
方法进行存根-也就是说,您指定调用performRequest
时应发生的情况。
但这创造了竞争条件。该测试的行为是不确定的,因为我们无法确定RequestQueue
线程是在存根调用之前还是之后都到达了对performRequest
的调用。因此,您可能会获得该方法的原始版本,也可能会获得存根版本。确保唯一的方法是重新设计测试的工作方式。
您确实需要先对performRequest
进行存根,然后启动RequestQueue
线程。可能最简单的事情是在完成所有存根之后将mMainRequestQueue.start();
向下移动到@Test
方法中。