Robolectric测试需要等待的东西在一个线程 [英] Robolectric test needs to wait for something on a thread

查看:1469
本文介绍了Robolectric测试需要等待的东西在一个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的类做这样的:

public void doThing() {
    Doer doer = new Doer();
    Thread thread = new Thread(doer);
    thread.start();
}

在'实干家'类是一个内部类:

The 'Doer' class is an inner class:

private class Doer implements Runnable {
    public void run() {
        Intent myIntent = new Intent(mContext, MyService.class);
        mContext.startService(myIntent);

        ...Some more stuff...
    }

这工作得很好。

我需要测试这一点使用Robolectric。当然 doThing()立即返回,我需要给线程有机会运行之前我

I need to test this using Robolectric. Naturally doThing() returns immediately and I need to give the thread a chance to run before I do

ShadowApplication.getInstance().getNextStartedService()

我怎么能等待线程运行?

How can I wait for the thread to run?

我曾尝试:

Robolectric.flushForegroundThreadScheduler();
Robolectric.flushBackgroundThreadScheduler();

和他们都没有达到预期效果:他们我的意图之前都返回已发送

and neither has the desired effect: they both return before my Intent has been sent.

目前我已经通过把睡眠到我的测试周围工作的时刻:

At the moment I have worked around it by putting a sleep into my test:

Thread.sleep(10);

和它的伎俩,但它显然是可怕的 - 这是等着使我悲痛的竞争条件

and it does the trick, but it's clearly horrible - it's a race condition waiting to cause me grief.

推荐答案

下面是一个工作的例子。

Here is a working example.

请注意,它依赖于一个电话告诉Robolectric使现场HT​​TP查询:

Note that it relies on a call to tell Robolectric to enable live HTTP queries:

FakeHttp.getFakeHttpLayer().interceptHttpRequests(false);

在code一ConditionVariable管理后台任务的完成跟踪。

The code a ConditionVariable to manage tracking of completion of the background task.

我不得不加入到我的项目的的build.gradle文件(在依赖块):

I had to add this to my project's build.gradle file (in the dependencies block):

// http://robolectric.org/using-add-on-modules/
compile 'org.robolectric:shadows-httpclient:3.0'
testCompile 'org.robolectric:shadows-httpclient:3.0'

我希望这有助于!

I hope this helps!

皮特

// This is a dummy class that makes a deferred HTTP call.
static class ItemUnderTest {

  interface IMyCallbackHandler {
    void completedWithResult(String result);
  }

  public void methodUnderTestThatMakesDeferredHttpCall(final IMyCallbackHandler completion) {
    // Make the deferred HTTP call in here.
    // Write the code such that completion.completedWithResult(...) is called once the
    // Http query has completed in a separate thread.

    // This is just a dummy/example of how things work!
    new Thread() {
      @Override
      public void run() {
        // Thread entry point.
        // Pretend our background call was handled in some way.
        completion.completedWithResult("Hello");
      }
    }.start();
  }
}

@org.junit.Test
public void testGetDetailedLatestResultsForWithInvalidEmailPasswordUnit_LiveQuery() throws Exception {

  // Tell Robolectric that we want to perform a "Live" test, against the real underlying server.
  FakeHttp.getFakeHttpLayer().interceptHttpRequests(false);

  // Construct a ConditionVariable that is used to signal to the main test thread,
  // once the background work has completed.
  final ConditionVariable cv = new ConditionVariable();

  // Used to track that the background call really happened.
  final boolean[] responseCalled = {false};

  final ItemUnderTest itemUnderTest = new ItemUnderTest();

  // Construct, and run, a thread to perform the background call that we want to "wait" for.
  new Thread() {
    @Override
    public void run() {
      // Thread entry point.
      // Make the call that does something in the background...!
      itemUnderTest.methodUnderTestThatMakesDeferredHttpCall(
          new ItemUnderTest.IMyCallbackHandler() {
            @Override
            public void completedWithResult(String result) {
              // This is intended to be called at some point down the line, outside of the main thread.
              responseCalled[0] = true;

              // Verify the result is what you expect, in some way!
              org.junit.Assert.assertNotNull(result);

              // Unblock the ConditionVariable... so the main thread can complete
              cv.open();
            }
          }
      );

      // Nothing to do here, in particular...
    }
  }.start();

  // Perform a timed-out wait for the background work to complete.
  cv.block(5000);

  org.junit.Assert.assertTrue(responseCalled[0]);
}

这篇关于Robolectric测试需要等待的东西在一个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆