Как выполнить модульное тестирование BackgroundWorker C#

Я пытаюсь выполнить модульное тестирование, используя следующий метод модульного тестирования VS.

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

вот юнит-тестер

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

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

Единственная проблема заключается в том, что внутренняя реализация использует BackgroundWorker, поэтому обратный вызов вызывается в другом потоке. Вот внутренняя реализация.

    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");
    }

Конечно, поскольку Get() возвращается сразу же, тест завершается успешно и тестирование останавливается, поэтому RunWorkerCompleted никогда не будет выполнен. Я могу легко проверить это с помощью обычного приложения (WPF), потому что оно продолжает работать, но я хотел бы иметь возможность модульного тестирования.

Любые идеи? Заранее спасибо.


person Sherlock    schedule 11.09.2009    source источник


Ответы (3)


Что-то вроде:

[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);
}

Хотя вы, вероятно, захотите добавить что-то туда, чтобы остановить выполнение теста навсегда, если он не пройден...

person Martin Harris    schedule 11.09.2009

Я не знаю подробностей о C# и BackgroundWorker, но я бы сделал это, внедрив реализацию BackgroundWorker и во время теста использовал заглушенный BackgroundWorker, которым вы можете управлять, когда он выполняется и в каком потоке. Если требуется связь между двумя потоками, заглушенный BackgroundWorker создаст новый поток и приостановит тест до его завершения, если не принудительно запустить его после вызова get.

person Michael Lloyd Lee mlk    schedule 11.09.2009
comment
Как вы могли это сделать, если BackgroundWorker не реализует никаких интерфейсов? - person Nick; 02.10.2013
comment
Вы можете создать свой собственный класс, который обертывает BackgroundWorker и реализует интерфейс, а затем подделать его. - person reggaeguitar; 11.05.2016