Как выполнить модульный тест BackgroundWorker C # - PullRequest
4 голосов
/ 11 сентября 2009

Я пытаюсь выполнить модульное тестирование, используя средство модульного тестирования 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), потому что оно продолжает работать, но мне бы хотелось иметь возможность модульного тестирования.

Есть идеи? Заранее спасибо.

Ответы [ 3 ]

7 голосов
/ 11 сентября 2009

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

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

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

4 голосов
/ 11 сентября 2009

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

0 голосов
/ 11 сентября 2009

Я написал похожий код и сделал его тестируемым, следуя шаблону IAsyncResult .Мои модульные тесты работают с синхронной (блокирующей) версией метода.Асинхронные методы могут состоять из одной строки, поэтому я не писал для них модульные тесты.

...