c# – 如何对包含异步调用的方法进行单元测试?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 如何对包含异步调用的方法进行单元测试?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2047字,纯文字阅读大概需要3分钟。
内容图文
![c# – 如何对包含异步调用的方法进行单元测试?](/upload/InfoBanner/zyjiaocheng/806/fefda0bd0c154946952025f8563708ac.jpg)
我有一个包含这样的异步调用的方法:
public void MyMethod() {
...
(new Action<string>(worker.DoWork)).BeginInvoke(myString, null, null);
...
}
我正在使用Unity并且创建模拟对象不是问题,但是如何在不担心竞争条件的情况下测试DoWork的调用?
一个previous question提供了一个解决方案,但在我看来,等待处理是一个黑客(竞争条件仍然存在,虽然它几乎不可能提出).
编辑:好的,我想我可以用一般的方式提出这个问题,但似乎我必须进一步详细说明这个问题:
我想为上面提到的MyMethod创建一个测试,所以我做了这样的事情:
[TestMethod]
public void TestMyMethod() {
...setup...
MockWorker worker = new MockWorker();
MyObject myObj = new MyObject(worker);
...assert preconditions...
myObj.MyMethod();
...assert postconditions...
}
天真的方法是创建一个MockWorker(),它在调用DoWork时简单地设置一个标志,并在后置条件中测试该标志.这当然会导致竞争条件,其中在MockWorker中设置标志之前检查后置条件.
更正确的方法(我可能最终会使用)是使用等待句柄:
class MockWorker : Worker {
public AutoResetEvent AutoResetEvent = new AutoResetEvent();
public override void DoWork(string arg) {
AutoResetEvent.Set();
}
}
…并使用以下断言:
Assert.IsTrue(worker.AutoResetEvent.WaitOne(1000, false));
这是使用类似信号量的方法,这很好……但理论上可能会发生以下情况:
>在我的DoWork代理上调用BeginInvoke
>由于某种原因,主线程或DoWork线程都没有给出1000ms的执行时间.
>主线程被赋予执行时间,并且由于超时,断言失败,即使DoWork线程尚未执行.
我误解了AutoResetEvent的工作原理吗?我只是太偏执了,还是有一个聪明的解决方案来解决这个问题?
解决方法:
等待句柄将是我的方式. AFAIK(我当然不知道)异步方法正在使用等待句柄来触发该方法.
我不确定为什么你认为比赛条件会发生,除非你在WaitOne电话上给出了异常短的时间.我会在waitone上放4-5秒,这样你就可以确定它是否被打破了,这不仅仅是一场比赛.
另外,不要忘记等待句柄如何工作,只要创建了等待句柄,就可以执行以下执行顺序a
>线程1 – 创建等待句柄
>线程1 – 设置等待句柄
>线程2 – 等待句柄上的waitone
>线程2 – 吹过等待句柄并继续执行
即使正常执行也是如此
>线程1 – 创建等待句柄
>线程2 – 等待句柄上的waitone
>线程1 – 设置等待句柄
>线程2 – 吹过等待句柄并继续执行
要么正常工作,可以在Thread2开始等待之前设置等待句柄,并为您处理所有事情.
内容总结
以上是互联网集市为您收集整理的c# – 如何对包含异步调用的方法进行单元测试?全部内容,希望文章能够帮你解决c# – 如何对包含异步调用的方法进行单元测试?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。