简体   繁体   English

如何单元测试BackgroundWorker C#

[英]How to Unit test BackgroundWorker C#

I'm trying to unit test, using VS unit testing facility following method. 我正在尝试进行单元测试,使用VS单元测试设备跟随方法。

void Get(string name, Action<string> callBack);

here is unit tester 这是单元测试仪

    [TestMethod]
    public void Test()
    {
        Action<string> cb = name =>
        {
            Assert.IsNotNull(name);
        };

        var d = new MyClass();
        d.Get("test", cb);
    }

The only problem is that internal implementation uses BackgroundWorker, hence callback is invoked on another thread. 唯一的问题是内部实现使用BackgroundWorker,因此在另一个线程上调用回调。 Here is internal implementation. 这是内部实施。

    public void Get(string name, Action<string> callBack)
    {
        callBackString = callBack;
        GetData(name);
    }  

    private void GetData(string name)
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.RunWorkerAsync(name);
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //do work here
        if (null != callBackString)
            callBackString("ok");
    }

Of course because Get() returns right away, test completes with success and testing stops, thus RunWorkerCompleted never gets to be executed. 当然因为Get()立即返回,测试完成并且测试停止,因此RunWorkerCompleted永远不会被执行。 I can easily test this via normal application (WPF) because it stays running, yet I'd like to have ability to unit test this. 我可以通过普通应用程序(WPF)轻松测试它,因为它仍在运行,但我希望能够对此进行单元测试。

Any ideas? 有任何想法吗? Thanks in advance. 提前致谢。

Something like: 就像是:

[TestMethod]
public void Test()
{   
    bool running = true;
    string result = null;

    Action<string> cb = name =>
    {
        result = name;
        running = false;
    };

    var d = new MyClass();
    d.Get("test", cb);

    while(running)
    {
        Thread.Sleep(100);
    }

    Assert.IsNotNull(result);
}

Though you probably want to add something in there to stop the test from running forever if it fails... 虽然您可能希望在其中添加一些内容以阻止测试在其失败时永远运行...

I don't know the details for C# & BackgroundWorker but I'd do this by injecting the BackgroundWorker implementation and during the test use a stubbed BackgroundWorker that you can control when it executions and in which thread. 我不知道C#和BackgroundWorker的细节,但是我通过注入BackgroundWorker实现来实现这一点,并且在测试期间使用了一个存根的BackgroundWorker,您可以在执行时控制它以及在哪个线程中控制它。 If communication between two threads is required then have the stubbed BackgroundWorker create a new thread and have the test pause until it is complete, if not force it to run after the call to get. 如果需要两个线程之间的通信,那么让存根的BackgroundWorker创建一个新线程并让测试暂停直到它完成,如果没有强制它在get调用之后运行。

I've written similar code and made it testable by following the IAsyncResult design pattern . 我编写了类似的代码,并通过遵循IAsyncResult设计模式使其可测试。 My unit tests run against the synchronous (blocking) version of the method. 我的单元测试针对该方法的同步(阻塞)版本运行。 The asynchronous methods can be a single line each, so I didn't write unit tests against those. 异步方法每个都可以是一行,所以我没有针对这些方法编写单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM