c# - 如何在测试方法上触发 AutoResetEvent 等待句柄?
问题描述
在 C# 中的自动化测试 (MSTest) 中工作时,测试方法从外部库调用方法,然后它必须等到触发事件,发出操作完成的信号。
我正在尝试使用本文中描述的方法:
[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 窗体应用程序而不是测试方法调用此方法,我验证了该事件是否正确触发。
“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
EDIT2:即使在测试了建议使用单独线程的方法之后,这仍然不起作用。
我尝试在 WindowsForms 项目(而不是在单元测试项目中)中使用这些方法(即使不是必需的),以确保没有缺少程序集或测试的执行方式。
所以我得到了同样的行为。我怀疑主线程中的某些东西阻止了 autoresetevent 正确设置。
——伊戈尔
解决方案
我个人建议在操作某些对象事件时不要使用 AWAIT 表达式,事件总是从 main_thread 触发,因此如果您处于等待链进程中,该事件将永远无法通知主线程。
您可以做的一种方法是为预期的操作创建一个新线程,它不会锁定主线程。
推荐阅读
- python - 从本地库导入 selenium 异常导致异常处理失败
- android-studio - 为什么 Kotlin toIntOrNull() 在大数上返回 null?
- ios - SwiftUI:如何将垂直顶部与 VStack 对齐?
- java - 如何循环通过 java.io 异常 (502)?
- file - 未找到 Flutter & Dart 文件路径
- python - Python - 尽管使用了 df.loc,但仍获得“SettingWithCopyWarning”
- jquery - 在电子邮件中使用带有背景 url 的 base64
- mysql - MYSQL 批量插入但分配唯一的个性化标签
- java - 尝试使用 AWS SDK 从 Java 应用程序连接 SQS 时出现 403 禁止错误
- javascript - 如何在脚本中使用多个输入