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

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());

希望这会有所帮助!

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

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

相关文档推荐

Android Mocking a Dagger2 injected dependency for a Espresso test(Android 为 Espresso 测试模拟 Dagger2 注入依赖项)
Mock object in Android Unit test with kotlin - any() gives null(使用 kotlin 在 Android 单元测试中模拟对象 - any() 给出 null)
How to mock Context using Mockito?(如何使用 Mockito 模拟上下文?)
Unit test Android, getString from resource(单元测试Android,从资源中获取字符串)
Mockito - what does verify method do?(Mockito - 验证方法有什么作用?)
Unit Testing in Retrofit for Callback(回调改造中的单元测试)