Как сделать так, чтобы дескриптор ожидания AutoResetEvent запускался в тестовом методе? - PullRequest
0 голосов
/ 03 июля 2019

При работе в автоматическом тесте (MSTest) в C #, где метод теста вызывает метод из внешней библиотеки, а затем должен ждать, пока событие не будет запущено, сигнализируя о завершении операции.

Я пытаюсь использовать подход, описанный в этой статье :

[Test]
public void TestEventualEventTimesOut() {
  AutoResetEvent _autoResetEvent = new AutoResetEvent(false);
  var actual = string.Empty;

  var aClass = new AClass();
  aClass.SomethingHappened += (_, s) => { actual = s; _autoResetEvent.Set(); };

  aClass.DoSomethingThatFiresAnEventEventually("A");


  Assert.IsFalse(_autoResetEvent.WaitOne());
  Assert.AreEqual("", actual);
}

Проблема в том, что "SomethingHappened" никогда не запускается.

Я убедился, что событие правильно сработало, если этот метод вызывается, например, из приложения Windows Forms, а не из метода теста.

Метод «DoSomethingThatFiresAnEventEventually» внутренне также вызывает некоторые методы, и в дальнейшем некоторые события будут вызваны, когда, наконец, будет запущено событие SomethingHappened.

Я также пытался использовать стратегию TaskCompletionSource из этого потока , но без изменений в поведении.

Я пытаюсь понять, почему это не работает в моем методе тестирования? Любые идеи горячие, чтобы отладить это?

РЕДАКТИРОВАТЬ: Это код из подхода TaskCompletionSource:

TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();

        myObject.RefreshReady += (_, s) =>
        {
            //never hit
            tcs.TrySetResult(null);
        };

        myObject.Refresh();

        await tcs.Task;

        Assert.Fail(); //never hit

РЕДАКТИРОВАТЬ2: Даже после тестирования подхода, предложенного использовать отдельный поток, это все еще не работает.

Я пытался использовать эти подходы (даже если в этом нет необходимости) в проекте WindowsForms (не в проекте модульных тестов), чтобы убедиться, что не пропущена сборка или что-то с тем, как выполняются тесты.

Так что у меня такое же поведение. Я подозреваю, что что-то в главном потоке блокирует автоматическое восстановление событий для правильной установки.

- Игорь

1 Ответ

0 голосов
/ 03 июля 2019

Я лично рекомендую не использовать выражение AWAIT при манипулировании некоторыми событиями объекта, события всегда запускаются из main_thread, поэтому, если вы находитесь в процессе цепочки ожидания, событие никогда не сможет уведомить основной поток.

Один из подходов, который вы можете использовать, - это создать новый поток для намеченной операции, и он не заблокирует основной поток.

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