鉴于.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");
复制代码

2017-11-30 15:26:34

转载于:https://juejin.im/post/5ce55aa3e51d4576bc1a0d58

.NET单元测试(五):多线程相关推荐

  1. C#多线程学习(五) 多线程的自动管理(定时器) (转载系列)——继续搜索引擎研究...

    Timer类:设置一个定时器,定时执行用户指定的函数.               定时器启动后,系统将自动建立一个新的线程,执行用户指定的函数. 初始化一个Timer对象: Timer timer ...

  2. Java之多线程学习笔记五 —— 多线程模拟龟兔赛跑

    Java之多线程学习笔记五 -- 多线程模拟龟兔赛跑 参考教程B站狂神https://www.bilibili.com/video/BV1V4411p7EF package pers.ylw.less ...

  3. JUnit单元测试中多线程的坑

    一.JUnit单元测试方法不输出 在JUnit的@Test方法中启用多线程,新启动的线程会随着@Test主线程的死亡而不输出 二.解决方法 在@Test方法中每创建一个线程,就join一下,这样我们新 ...

  4. 【机器视觉】 HDevelop语言基础(五)-多线程

    00. 目录 文章目录 00. 目录 01. 概述 02. 启动线程 03. 等待子线程结束 04. HDevelop中线程的执行 05. 监视线程 06. 挂起和恢复线程 06. 附录 01. 概述 ...

  5. [19/04/12-星期五] 多线程_任务定时调度(Timer、Timetask和QUARTZ)

    一.Timer和Timetask 通过Timer和Timetask,我们可以实现定时启动某个线程. java.util.Timer 在这种实现方式中,Timer类作用是类似闹钟的功能,也就是定时或者每 ...

  6. C#多线程学习(五) 多线程的自动管理(定时器)

    Timer类:设置一个定时器,定时执行用户指定的函数.               定时器启动后,系统将自动建立一个新的线程,执行用户指定的函数. 初始化一个Timer对象: Timer timer ...

  7. 在Eclipse中使用JUnit4进行单元测试

    在Eclipse中使用JUnit4进行单元测试 http://www.sina.com.cn  2010年01月18日 14:08  IT168.com [IT168 技术文档]我们在编写大型程序的时 ...

  8. C#多线程学习(四) 多线程的自动管理(线程池) (转载系列)——继续搜索引擎研究...

    在多线程的程序中,经常会出现两种情况: 一种情况:   应用程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,然后才能给予响应                   这一般使用ThreadPo ...

  9. 艾伟:C#多线程学习(六) 互斥对象

    本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操纵一个线程 C#多线程学习(三) 生产者和消费者 C#多线程学习(四) 多线程的自动管理(线程池) C#多线程学习( ...

  10. C# 多线程学习总结

    C#多线程学习(一) 多线程的相关概念 什么是进程? 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源.而一个进程又是由多个线程所组成的. 什么是线程? 线程是 ...

最新文章

  1. android网络游戏开发实战pdf_Python项目开发实战+第2版PDF高清文档下载
  2. hihoCoder #1384 : Genius ACM [枚举+倍增]
  3. AI理论知识基础(21)-对变化建模-用差分方程-动力系统及常数解
  4. 深交所与工信部签署优质中小企业上市培育战略合作协议
  5. LINUX下的GNU调试工具,GNU调试器 GDB 8.3 发布及安装更新,支持RISC-V与IPv6连接等
  6. 语法的集合?协议可没那么简单
  7. matlab索引超出数组边界且不提示数组边界的一种处理办法
  8. 弘辽科技:直通车引流逻辑。
  9. 随机数相关函数rand与srand 以及drand48()与srand48
  10. 0门槛项目,闲鱼卖特价电影票,免费低价票源
  11. mysql table already_MySQL优化表时提示 Table is already up to date的解决方法
  12. 【杂烩】Tesla M40 24G 在Win11上的双显卡显示实现、改风冷
  13. BAT 字符串大小写转换
  14. 基于Java毕业设计影院网上售票系统源码+系统+mysql+lw文档+部署软件
  15. 数据可视化 信息可视化_数据可视化极性
  16. 一体化运维:挖矿病毒可能正在蚕食你的IT资源
  17. 从零构建FLINK整合Drools动态规则实时运营系统(项目案例)第1篇(项目介绍篇)
  18. 计算机远程桌面在什么地方查找,远程桌面连接怎么使用,远程桌面连接在哪里...
  19. 315/433M 无线发射芯片 XL4456 功能和用途简单介绍
  20. 国外的站长如何做SEO优化?

热门文章

  1. 别怨自己命不好,先看看“厚德载物”你有几德?
  2. libcurl 发送邮件_libcurl smtp发送邮件附件大小限制问题
  3. 长春技师学院计算机系,长春技校排名前五十
  4. html target=_blank 弹出独立窗口,HTML base 标签的 target 属性 —— base target=_blank /...
  5. js 键盘事件 理解
  6. liunx服务器间拷贝文件,linux 不同服务器之间拷贝文件
  7. echarts 按需引入模_【React】react项目引入echarts插件
  8. 时间java_Java 日期时间
  9. python 3.8.5 打包_骚操作 | Python 实现在 App 端的人脸识别
  10. 中南大学MATLAB变量专题/矩阵的建立1-3/4