鉴于.NET Framework 4.5后.NET增加了对 async/await 的支持,本文讨论的异步内容均基于async/await

  客户端界面开发,多线程是逃不了的话题,而多线程的加入势必对程序的稳定性带来挑战,单元测试就显得更为重要。相对于同步代码的测试,多线程单元测试有更多细节需要注意。

async void 和 async Task。

  假设某一天你运气不好,需要为类似如下的方法补充单元测试:

public static bool Changed;public static async void ChangeAsync()
{await Task.Run(() =>{Task.Delay(1000);Changed = true;});
}

你发现,要测试此方法需要用一些奇葩的方式,比如:

[TestMethod()]
public void ChangeAsyncTest_OriginalFalse_ChangeToTrue()
{AsyncClient.Changed = false;AsyncClient.ChangeAsync();Thread.Sleep(1100);Assert.IsTrue(AsyncClient.Changed);
}

显然,这种延时等待是极其恶心的,如果ChangeAsync方法返回的不是void而是Task,我们就可以愉快的await了:

[TestMethod()]
public async Task ChangeAsyncTest_OriginalFalse_ChangeToTrue()
{AsyncClient.Changed = false;await AsyncClient.ChangeAsync();Assert.IsTrue(AsyncClient.Changed);
}

需要特别注意的是,在异步单元测试方法中也必须返回Task,这是MSTest的约定,否则这个测试方法无法运行起来。(实际上MSTest也需要使用返回的Task来收集异常,关于这部分更多内容可以参见Async/Await最佳实践)

抛弃ExpectedException

  在测试程序是否按照预期的抛出了异常,我们常常会用ExpectedException,这家伙有一个问题,它是对整个测试方法的方法体做捕获,也就是说测试方法中的非action代码抛出了异常依然能够被ExpectedException捕获,这就造成潜在的bug,为了解决此问题,在MSTest V2之前往往需要写一些辅助方法,但MSTest V2断言库中增加了Assert.ThrowsExceptionAsync和Assert.ThrowsException,可以精确的定位在哪段代码中抛出了异常。假设我们的被测代码跟下面类似:

public static async Task ChangeAsync()
{await Task.Run(() =>{throw new InvalidOperationException();});
}

测试代码可以这样写:

[TestMethod()]
public async Task ChangeAsyncTest_ThrowInvalidOperationException()
{await Assert.ThrowsExceptionAsync<InvalidOperationException>(async () =>{await AsyncClient.ChangeAsync();});
}

异步方法mock

  在moq中,异步方法的mock也是极其简单的,假设有这样的接口:

public interface ITextReader
{Task<string> ReadTextAsync();
}

测试代码中mock其返回结果可以有如下两种写法:

var mockTextReader = new Mock<ITextReader>();//可以这样
mockTextReader.Setup(x => x.ReadTextAsync()).Returns(async ()=>await Task.FromResult("mockValue"));//也可以这样
mockTextReader.Setup(x => x.ReadTextAsync()).ReturnsAsync(()=> "mockValue");

date: 2017-11-30 15:26:34

转载于:https://www.cnblogs.com/erdao/p/8419661.html

.NET单元测试-多线程相关推荐

  1. Junit单元测试多线程

    Junit单元测试多线程 Main方法里执行多线程 vs 使用Junit测试多线程 main方法调用结果 Junit测试结果 解决方法 先说结论:Junit不支持多线程,在主线程执行完后,无论是否是守 ...

  2. android 单元测试 多线程,多线程之单元测试(Junit)

    多线程测试服务 1.新建一个核心数为100 的线程池 ExecutorService service = Executors.newFixedThreadPool(100); 2.执行一个阻塞不大的任 ...

  3. android 单元测试 多线程,单元测试多线程Android RxJava

    您可以编写自己的ThreadFactory ThreadFactory custom = new CustomThreadFactory(); ExecutorService executorServ ...

  4. C++多进程并发框架FFLIB

    三年来一直从事服务器程序开发,一直都是忙忙碌碌,不久前结束了职业生涯的第一份工作,有了一个礼拜的休息时间,终于可以写写总结了.于是把以前的开源代码做了整理和优化,这就是FFLIB.虽然这边总结看起来像 ...

  5. 《构建之法》第二章读书摘要

    第二章   个人技术和流程 <构建之法>第二章主要讲了个人技术和流程,因为团队需要一定的流程来管理开发活动,每个工程师在软件生命周期所做的工作也应该有一个流程,这一章中着重介绍PSP,即个 ...

  6. 【Java单元测试】如何进行单元测试、异常测试、参数化测试、超时测试、测试多线程

    Junit单元测试的步骤 (1)新建一个单元测试 (2)选择位置 (3)选择需要测试的方法 (4)是否将Junit 4添加到ClassPath中 (5)自动生成的测试类 (6) 然后就可以编写单元测试 ...

  7. 多线程的单元测试工具 - GroboUtils

    写过Junit单元测试的同学应该会有感觉,Junit本身是不支持普通的多线程测试的,这是因为Junit的底层实现上,是用System.exit退出用例执行的.JVM都终止了,在测试线程启动的其他线程自 ...

  8. 多线程junit单元测试

    junit中测试完成后会进行jvm退出,而不是线程退出,所以任一线程退出都会导致测试结束,junit想进行多线程测试需要进行另外包装,网上看到一个投机取巧的例子还不错,贴上我的测试代码(代码中我需要测 ...

  9. .NET单元测试(五):多线程

    鉴于.NET Framework 4.5后.NET增加了对 async/await 的支持,本文讨论的异步内容均基于async/await   客户端界面开发,多线程是逃不了的话题,而多线程的加入势必 ...

最新文章

  1. 网站建设全阶段培养共分三期
  2. 网站维护:利用iptables和ipset屏蔽恶意IP的访问
  3. WebApiClient的JsonPatch局部更新
  4. matlab浮点数求绝对值_MATLAB仿真阵列天线切比雪夫综合法(附代码)
  5. 如何在Java中找到整数的质因数–因式分解
  6. java 可重入读写锁 ReentrantReadWriteLock 详解
  7. PSD分层模板素材|电商页面这样设计,转化率成倍提高!
  8. SQL注入学习part04:(结合sqli-libs学习:31-40关)
  9. 25 岁的老 Delphi,还值得程序员入手吗?
  10. Redis普通分布式锁
  11. Linux16.04与win10搭建samba服务器
  12. 苹果mac3D模型渲染软件:KeyShot
  13. UEditor使用说明
  14. Android 11.0 12.0系统添加水印(仿安全模式水印)
  15. python获取gps_Python GPS模块:读取最新的GPS D
  16. python——设置渐变色
  17. [转]库存那些事儿_8_盘点
  18. 斯特林公式 ——Stirling公式(取N阶乘近似值)
  19. Clonezilla制作镜像、恢复
  20. php苹果内购验证,苹果内购支付校验

热门文章

  1. oracle 单表查重,Oracle如何用单字段或多字段进行查重
  2. 计算机专业能进教育局吗,教育局一般招什么专业
  3. AcWing 1738. 蹄球(特殊基环树)
  4. php 126 发邮件,解析php中用PHPMailer来发送邮件的示例(126.com的例子)
  5. 因果推断笔记——自整理因果推断理论解读(七)
  6. R学习笔记(4): 使用外部数据
  7. Nova 操作汇总(限 libvirt 虚机) [Nova Operations Summary]
  8. USB2.0学习笔记连载(四):安装Cypress官网套件
  9. filestream streamreader
  10. 不要把a href=当作按钮用