单元测试网络响应.在调试时工作,而不是在实际运行时工作

Unit testing a network response. Works when debugging, not when actually running(单元测试网络响应.在调试时工作,而不是在实际运行时工作)
本文介绍了单元测试网络响应.在调试时工作,而不是在实际运行时工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我目前正在尝试测试是否确实收到了网络响应.

I am currently attempting to test that a network response is actually being received.

虽然我知道这不是我在测试方面应该做的事情,但这是我自己的好奇心,如果可能的话,我想继续.

就目前而言,我已经成功创建了测试.请求被毫无问题地发送到排球队列.

As it stands, I have successfully created the test. A request is sent to a volley queue without issue.

现在奇怪的部分:

该请求永远不会执行.这是我如何测试它的想法:

That request is never executed. Here's an idea of how I'm testing it:

 @Test
    public void testSimpleGetResponseFromServerVolley() throws Exception {
        final CountDownLatch signal = new CountDownLatch(1);

        NetworkClass.NetworkListener listener = new NetworkClass.NetworkListener() {
            @Override
            public void onResponse(Response response) {
                assertThat(response != null);
                System.out.println("Got Response");
                signal.countDown();

            }

            @Override
            public void onError(Throwable error) {
                System.out.println("No Response");
                signal.countDown();
            }
        };
        NetworkClass.getResponseFromServer(null, listener);
        signal.await();
    }

此代码意外导致测试挂起并且永远无法完成.

This code unexpectedly causes the test to hang and never complete.

然而,这是我不再对情况失去理解的地方:

如果我通过 debug 运行测试并逐行执行,则测试成功执行,并收到响应.

If I run the test via debug and step through line by line, the test successfully executes, and response is received.

我认为正在发生的事情:

当我通过调试单步执行时,volley requestQueue 成功进行并发出请求,并在调用 await() 之前收到响应.

When I step through via debug, the volley requestQueue successfully carries on and makes the request, and the response is received before await() is called.

当我不通过调试单步执行时,await() 会阻塞处理所有这些的线程.

When I don't step through via debug, await() is blocking the thread which handles all of that.

关于如何处理这个问题的任何想法?

Any ideas on how I can handle this?

推荐答案

Volley 依赖 Looper.getMainLooper() 来处理其执行.当使用 RobolectricTestRunner 时,Robolectric 会对此进行模拟,因此它不会正确设置,从而导致测试失败.

Volley relies on Looper.getMainLooper() to handle its executions. When using a RobolectricTestRunner, Robolectric mocks this out and as such it will not be correctly set up, thus resulting in a failed test.

在我的具体情况下,当我使用断点时,系统实际上确实设置了主循环器,因为系统正在利用它来显示断点/调试工具.因此,这描述了我最初的问题中发现的行为背后的原因.

In my specific case, when I was using breakpoints, the system actually does set up the main looper, because the system is utilizing it to show the breakpoints / debugging tools. This thus describes the reasoning behind the behaviour found in my initial question.

现在,对于在单元测试期间使用 Volley 获得真实网络响应的解决方案,必须将执行程序更改为不使用主循环器.

Now for a solution as to getting real network responses with Volley during a unit test, the executor must be changed to not be using the main looper.

作为一个简单的解决方案,创建一个依赖于 Executor.singleThreadExecutor() 而不是 Main Looper 的请求队列.

As an easy solution, create a request queue that relies on Executor.singleThreadExecutor() instead of the Main Looper.

这就是我的意思:

    //Specific test queue that uses a singleThreadExecutor instead of the mainLooper for testing purposes.
public RequestQueue newVolleyRequestQueueForTest(final Context context) {
    File cacheDir = new File(context.getCacheDir(), "cache/volley");
    Network network = new BasicNetwork(new HurlStack());
    ResponseDelivery responseDelivery = new ExecutorDelivery(Executors.newSingleThreadExecutor());
    RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network, 4, responseDelivery);
    queue.start();
    return queue;
}

然后,在测试期间将其用作 Volley 的请求队列.

Then, use that as your request queue for Volley during the tests.

这里的关键是:

ResponseDelivery responseDelivery = new ExecutorDelivery(Executors.newSingleThreadExecutor());

希望这会有所帮助!

这篇关于单元测试网络响应.在调试时工作,而不是在实际运行时工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

本站部分内容来源互联网,如果有图片或者内容侵犯了您的权益,请联系我们,我们会在确认后第一时间进行删除!

相关文档推荐

How can I use CClistview in COCOS2d Android?(如何在 COCOS2d Android 中使用 CClistview?)
cocos2d-android: how to display score(cocos2d-android:如何显示分数)
Sqlite database not copied from asset folder Android(Sqlite 数据库未从资产文件夹 Android 复制)
SQLite Database Copy Appears Corrupted When Generated by Device and not Emulator(SQLite 数据库副本在由设备而不是模拟器生成时出现损坏)
Android file copy(安卓文件拷贝)
Android how to detect Copy event of Edittext in android(Android如何在android中检测Edittext的Copy事件)