如何让我的ActivityUnitTestCases与MessageQueue线程同步并调用我的Handler?

时间:2010-03-29 20:18:23

标签: android junit

我正在为Android中的ListActivity编写单元测试,它使用处理程序来更新ListAdapter。虽然我的活动在Android模拟器中工作,但在单元测试中运行相同的代码不会更新我的适配器:对sendEmptyMessage的调用不会在我的activity的Handler中调用handleMessage。

如何让我的ActivityUnitTestCase与MessageQueue线程同步并调用我的Handler?

活动的代码有点像这样:

public class SampleActivity extends ListActivity implements SampleListener {
    List samples = new ArrayList();

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.sample_list);
        listView.setEmptyView(findViewById(R.id.empty));
    }

    private final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // unit test never reaches here
            sharesAdapter = new SampleAdapter(SampleActivity.this, samples);
            setListAdapter(sharesAdapter);
        }
    };

    public void handleSampleUpdate(SampleEvent event) {
        samples.add(event.getSample());
        handler.sendEmptyMessage(0);
    }
}

我的单元测试的代码有点像这样:

public class SampleActivityTest extends ActivityUnitTestCase<SampleActivity> {

    public SampleActivityTest() {
        super(SampleActivity.class);
    }

    @MediumTest
    public void test() throws Exception {
        final SampleActivity activity = startActivity(new Intent(Intent.ACTION_MAIN), null, null);
        final ListView listView = (ListView) activity.findViewById(android.R.id.list);
        activity.handleSampleUpdate(new SampleEvent(this));
        // unit test assert fails on this line:
        assertTrue(listView.getCount() == 1);
    }

}

1 个答案:

答案 0 :(得分:2)

我怀疑但是我不确定这是因为使用了检测线程而UIThread没有同步。所以你的处理程序绑定到创建它的线程。你的处理程序是在构造时创建的,所以它是调用构造函数的任何线程。我没有在我面前的消息来源,但我的猜测是,在大多数情况下,当应用程序运行时,我打赌它是UIThead(主要)两种构造,并在您的活动上调用onCreate()。但是当单元测试运行时,它被绑定到Instrumentation Thread,它可能构造你的活动,然后在UIThread上调用onCreate。现在你在检测线程中说,发送一条消息,你的线程没有与之关联的looper来做任何事情。所以它只是排在队列中。尝试将处理程序创建移动到onCreate()。这应该将您的Handler绑定到主循环器,然后您的异步事件将从另一个线程(检测线程)触发,并且UIThread将很乐意从队列中收集它们。

虽然我没有测试过,但这看起来似乎是第一眼的问题。