:)
我正面临使用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()));
行
同样的结果。
正如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;
}
...
networkDispatcher是在RequestQueue中创建的,使用“mocked”对象作为参数。所以我希望调用这个方法。
答案 0 :(得分:1)
在@Before
方法中,您启动RequestQueue
主题,然后调用performRequest
。稍后,在@Test
方法中,您将performRequest
方法存根 - 即指定调用performRequest
时应发生的情况。
但是这会造成竞争条件。此测试的行为是不确定的,因为我们无法判断RequestQueue
线程是否会在该调用被截断之前或之后到达performRequest
的调用。因此,您可能会获得该方法的原始版本,或者您可能会获得该存根版本。唯一可以确定的方法是重新设计测试的工作方式。
您确实需要首先存根performRequest
,然后启动您的RequestQueue
主题。可能最简单的做法是在完成所有存根之后将mMainRequestQueue.start();
向下移动到@Test
方法。