在C#中进行自动测试(MSTest)的过程中,该测试方法从外部库调用方法,然后必须等待事件被触发,表明操作已完成。
我正在尝试使用this article中描述的方法:
[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事件。
我还尝试使用this thread中的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
EDIT2:即使在测试了建议使用单独线程的方法之后,仍然无法使用。
我试图在WindowsForms项目(而不是在单元测试项目中)中使用这些方法(即使不是必需的),以确保不丢失程序集或执行测试的方式。
所以我也有同样的行为。我怀疑主线程中的某些内容阻止了autoresetevent的正确设置。
- 伊戈尔(Igor)
答案 0 :(得分:0)
我个人建议在处理某些对象事件时不要使用AWAIT表达式,事件总是从main_thread触发,因此,如果您处于等待链过程中,则该事件将永远无法通知主线程。
您可以执行的一种方法是为预期的操作创建一个新线程,并且该线程不会锁定主线程。