如何正确的单元测试调用UI的方法在另一个线程? [英] How to properly unit test calling UI method on another thread?

查看:194
本文介绍了如何正确的单元测试调用UI的方法在另一个线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有codeD的扩展方法(基于<一href="http://stackoverflow.com/questions/723532/gui-update-when-starting-event-handler-class-on-separate-thread/723584#723584">http://stackoverflow.com/questions/723532/gui-update-when-starting-event-handler-class-on-separate-thread/723584#723584):

Having coded an extension method (based on http://stackoverflow.com/questions/723532/gui-update-when-starting-event-handler-class-on-separate-thread/723584#723584):

public static class ControlExtensions
{
    public static TResult InvokeEx<TControl, TResult> (this TControl control,
                                                       Func<TControl, TResult> func)
      where TControl : Control
    {
        if (control.InvokeRequired)
            return (TResult)control.Invoke (func, control);

        return func (control);
    }
}

我一直在试图单元测试这种方法无论从UI线程和普通线程,我不能似乎能够做到这一点。

I've been trying to unit test this method both from a UI thread and a normal thread and I can't seem to be able to achieve that.

下面是单元测试code:

Here is the unit test code:

[Test]
public void TestInvokeExWithMethodReturningResultOnOtherThread ()
{
    // Prepare
    string result = string.Empty;
    var form = new Form ();
    var thread = new Thread (() =>
                             {
                                 result = form.InvokeEx (f => f.Text);
                             });

    // Execute
    thread.Start ();
    thread.Join (1000);

    // Verify
    Assert.That (result, Is.EqualTo ("Some label"));
}

测试通过,但如果我在 InvokeEx 方式(而不是调用)设置断点我看到的 Control.InvokeRequired 为假导致在 FUNC 方法直接调用。

The test passes but if I set a breakpoint in the InvokeEx method (not the call) I see that Control.InvokeRequired is false resulting in the func method directly called.

此外,现在的测试失败,因为结果未设置。

Furthermore, now the test fails because result is not set.

此外,同时通过code踩着我看到的 FUNC 方式被其他线程上执行(如预期),而不是在主线程中。

Additionally, while stepping through the code I see that the func method is executed on the other thread (as expected) and not on the main thread.

也许是因为我没有,因为我执行单元测试真正的UI线程?我将如何做到这一点,所有的消息抽?

Maybe it is because I do not have a real UI thread since I am executing a unit test? How would I achieve that and all the message pumping?

推荐答案

我一直在尝试不同的事情,我已经想出了以下内容:

I've been trying different things and I've come up with the following:

[Test]
public void TestInvokeExWithMethodReturningResultOnOtherThread ()
{
    // Prepare
    string result = string.Empty;
    var form = new Form ();
    var uiThread = new Thread (() => Application.Run (form));
    uiThread.SetApartmentState (ApartmentState.STA);
    uiThread.Start();
    Thread.Sleep (100);
    var thread = new Thread (() => result = form.InvokeEx (f => f.Text));

    // Execute
    thread.Start ();
    thread.Join ();
    form.InvokeEx (f => f.Close ());
    uiThread.Join ();

    // Verify
    Assert.That (result, Is.EqualTo ("Some label"));
}

现在,这完美的作品。

This now works perfectly.

请注意,我不得不添加的过载InvokeEx为无效的方法。

Note that I had to add an overload for InvokeEx for a void method.

这篇关于如何正确的单元测试调用UI的方法在另一个线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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