Ожидание запуска события в модульных тестах Silverlight - PullRequest
4 голосов
/ 15 декабря 2009

Я использую Silverlight Unit Testing Framework для тестирования некоторых классов View Manager. Некоторые тесты требуют запуска событий PropertyChanged .

В настоящее время я использую комбинацию EnqueueConditional и WaitHandles

Пример 1

[TestMethod]
[Asynchronous]
[Timeout(1000)]
public void TestNotificationExample()
{
    var manager = new UserManager();

    var waitHandle = new ManualResetEvent(false);
    manager.PropertyChanged += (sender, propChangArgs) =>
                                {
                                    waitHandler.Set();
                                };
    manager.DoTheThingThatTriggersNotification();
    // The notification event fires aynshronously to this
    EnqueueConditional (() => waitHandler.WaitOne(0));
    // Enqueue other tests here....
    EnqueueTestComplete();
}

Это работает. Но у меня есть вопросы к себе:

Мне действительно нужно использовать WaitHandle? Будет ли он работать так же хорошо, если бы я просто использовал bool?

Пример 2

bool fHasFiredEvent = false;
manager.PropertyChanged += (sender, propChangeArgs) =>
                           { 
                               fHasFiredEvent = true;
                           }
manager.DoTheThingThatTriggersNotification();    
EnqueueConditional (() => fHasFiredEvent);
EnqueueTestComplete();

Или было бы лучше, если бы я сохранил WaitHandle, но потерял атрибут Timeout и тайм-аут на ожидании?

Пример 3

[TestMethod]
[Asynchronous]
public void TestNotificationExample()
{
    var manager = new UserManager();

    var waitHandle = new ManualResetEvent(false);
    manager.PropertyChanged += (sender, propChangArgs) =>
                                {
                                    waitHandler.Set();
                                };
    manager.DoTheThingThatTriggersNotification();
    EnqueueCallback (() => Assert.IsTrue(waitHandler.WaitOne(1000));
    EnqueueTestComplete();
}

Итак, я написал три примера, и все они работают. Итак, мой последний вопрос

  • Что было бы лучше спектакль? (Хотя разница незначительна, и это чисто академический яда яда яда. Это интересно само по себе.)
  • У любого из трех примеров есть фундаментальные недостатки?

1 Ответ

5 голосов
/ 15 декабря 2009

Без реального запуска реального кода в трех примерах я не знаю, что могу дать авторитетный ответ, но мой совет - использовать # 2 и держаться подальше от # 1 и # 3.

Я пролистал источник для Silverlight Unit Test Framework Джеффа Уилкокса, и, насколько я помню, он использует умный, но действительно ужасный хак для EnqueueConditional, то есть он неоднократно вызывает предикат, переданный EnqueueConditional () в таймер / фоновый поток, проверяющий каждый раз, чтобы увидеть, если он возвращает истину. (Это не то, что вы хотите в производственном коде, но это достаточно хорошо для тестовой среды - логика, я полагаю.)

Так что, если ваш тест занимает пару секунд, я бы ожидал, что ваш waitHandler.WaitOne () any (a) будет вызываться много раз, блокируя каждый поток по ходу; или (b) заблокировать поток, который, как предполагается, может делать и другие вещи. Я предполагаю, что (с) также возможен, то есть вам может повезти, что WaitOne () не заблокирует ничего важного и будет вызван только один раз. Но, безусловно, # 2 - это «стандартный» способ использования этой тестовой среды, и если бы у вас не было конкретной причины представить более сложную логику WaitHandle, я бы не попытался подтолкнуть тестовую среду в этом направлении.

Тем не менее, если кто-то захочет осмотреться и дать более авторитетный ответ, я весь в ушах: -).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...