如何为异步方法编写单元测试用例?

2023-12-23

我想通过模拟依赖项来编写单元测试用例。整体流程如下。

我们有一个WorklistLoader它有一个异步方法LoadWorklistItemsAsync()。为了完成这个任务WorklistLoader依赖于下层 API(我想模拟)QueryManager.StartQueryTask(). StartQueryTask()也是一个异步方法,它查询文件系统并引发ProgressChanged()定期间隔,然后在最后提高CompletedEvent. StartQueryTask()返回对 TPL 的引用Task.

签字人StartQueryTask is

Task StartQueryTask(
    "SomeId",
    EventHandler<ProgressChanged> progressChanged,
    EventHandler<QueryCompleted> queryCompleted);

一旦WorklistLoader收到ProgressChanged事件来自QueryManager,它进行一些处理,然后提高其ProgressChanged事件(其中ViewModel已订阅)。

我想测试一下LoadWorklistItemsAsync()的方法WorklistLoader带着嘲笑QueryManager.StartQueryTask().

这是我的问题。

  1. 编写单元测试的最佳实践是什么Async()带有嘲笑的方法?
  2. 如何为依赖项使用 TPL 的方法编写单元测试用例?(方法返回Task type)

另一个问题是

  1. 如果我使用 Rhinomocks 模拟 QueryManager.StartQueryTask() 方法,它会是什么样子? (模拟代码。它必须引发progresschanged、completed 事件并返回Task)。

为了模拟某些东西,您需要能够将模拟注入到您正在使用的任何东西中。有很多方法可以做到这一点,使用控制反转容器、环境上下文引导代码等。最简单的方法是构造函数注入并引导环境上下文,以便在您想要测试时获得您想要的模拟。例如:

WorklistLoader worklistLoader;

[SetUp]
public void Setup()
{
    worklistLoader = new WorklistLoader(new MockQueryManager());
}

[Test]
public async Task TestWorklistLoader()
{
    await worklistLoader.LoadWorklistItemsAsync();
}

这也意味着 WorklistLoader 不依赖于QueryManager但取决于像这样的抽象IQueryManager that MockQueryManager将实施。

Where MockQueryManager可能是这样的:

public class MockQueryManager : IQueryManager
{
    public Task StartQueryTask() {/* TODO: */}
}

当然,您原来的 QueryManager 必须实现 IQueryManager:

public class QueryManager : IQueryManager
{
    public Task StartQueryTask() {/* TODO: */}
}

现在,在测试使用 TPL 的类时,您会注意到我已经实现了一个返回任务的异步测试方法。这告诉测试运行者在认为测试方法已经执行之前等待结果。如果你只是简单地写了这样的内容:

[Test]
public async void TestWorklistLoader()
{
    await worklistLoader.LoadWorklistItemsAsync();
}

跑步者将执行TestWorklistLoader它会立即返回LoadWorklistItemsAsync已完成并可能绕过任何断言。

Update:

如果您不使用 C# 5,那么我建议您只需等待单元测试中的任务完成即可。例如:

[Test]
public void TestWorklistLoader()
{
    var task = worklistLoader.LoadWorklistItemsAsync();
    if(!task.IsComplete()) task.Wait();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何为异步方法编写单元测试用例? 的相关文章

随机推荐

  • 为什么所有 NUL 都从我的脚本中删除?

    它看起来像 bash 还有 dash 从我的脚本中过滤掉任何 ASCII NUL printf test 000a echo test sh 1 printf test 001a echo test sh 2 printf ec 000ho
  • Heroku 混合内容 HTTPS/HTTP 问题

    我将应用程序部署到 Heroku 但在 Chrome 控制台中不断收到此错误 bundle js 11892 Mixed Content The page at https herokuapp com login was loaded ov
  • 跨线程编组 COM 接口的首选方法是什么?

    与 CoMarshalInterThreadInterfaceInStream 和 CoGetInterfaceAndReleaseStream 相比 使用 GIT 跨线程编组 COM 接口有哪些优点 缺点 是否有充分的理由选择一种方法而不
  • 解析 @username 的帖子

    我建立了一个类似 Twitter 的 replies 允许用户通过用户每日帖子相互联系 类似于 stackoverflow 以此作为指导https github com kltcalamay sample app compare origi
  • Spark DataFrame 和重命名多列 (Java)

    有没有更好的方法可以同时为给定 SparkSQL 的所有或多个列添加前缀或重命名DataFrame比多次调用dataFrame withColumnRenamed 一个例子是 如果我想检测更改 使用完整外连接 然后我就剩下两个了DataFr
  • Tensorflow 对象检测 api 验证数据大小

    我正在从对象检测 API 运行教程 并将 Oxford 数据集与 ResNet Faster RCNN 一起使用 当我通过运行 eval py 评估经过训练的模型时 Tensorboard 返回大约 0 95 的平滑精度值 我的问题是它评估
  • 我可以在 Django generic.ListView 中拥有多个列表吗?

    作为 Django 初学者 我正在研究 django 文档提供的教程 网址为https docs djangoproject com en 1 5 intro tutorial04 https docs djangoproject com
  • Android - 从收到的短信中获取日期和时间

    我正在开发一个 Android 应用程序 我需要在其中保存发件人 短信正文 日期和时间收到短信 现在我可以捕获消息正文和发件人 但我无法获取短信的日期和时间 即使我查看了 stackoverflow 中的一些帖子 但它们都没有捕获日期和时间
  • NSView 子类中的鼠标单击事件

    我有一个 NSView 子类 它使用 OpenGL 上下文进行初始化 并具有一堆鼠标事件处理 onMouseDown 等 我有一个使用它的应用程序 它有一个包含视图的主 Cocoa 窗口 并且所有鼠标事件都正常工作 但是 我现在尝试在另一个
  • 自动调整 UICollectionView 高度以适应其内容大小

    我有一个 UICollectionView 一个在集合视图中创建新单元格的按钮 我希望 UICollectionView 根据其内容大小调整其大小 当有一两个单元格时 UICollectionView 很短 如果有很多单元格 UIColle
  • 对话框服务内容中的换行符被忽略

    在剑道对话服务窗口的内容中插入换行符 rogress 中的 Kendo Angular 6 对话框 换行符将被忽略 尝试了 html 元素 br 和 n n 例如它在连续一行中显示字符文本 n n n const dialog Dialog
  • 如何向 CRM 2011 进行身份验证?

    我想建立一个简单的网站 客户可以在其中下订单和查看产品 此数据是我的 Microsoft Dynamics CRM 2011 环境 该数据是特定于客户的 因此我需要有关登录用户的信息 用户凭据存储在 CRM 2011 中 使用这些凭据 用户
  • Jython 的内存限制

    如何为我的 Jython 程序设置 JVM 内存限制 Java 的 Xmx 选项 我明白 Jython2 5引入 J 选项以便将选项发送到 JVM jython J Xmx8000m 但是 我必须与java1 6 0 23 上的 Jytho
  • android OAuth-2.0 google 使用 webview 登录获取用户信息

    我正在创建允许用户使用 facebook 或 google 帐户登录的应用程序 他们按下 登录 按钮 然后系统会要求他们使用 facebook 或 google 登录 当他们选择其中之一时 会弹出网络视图 问题是谷歌身份验证 阅读了一些文章
  • 清理带有标题的 URL 的最佳方法是什么

    清理 URL 的最佳方法是什么 我正在寻找这样的网址 什么是最好的头痛药物 我当前的代码 public string CleanURL string str str str Replace str str Replace str str R
  • 在不知道 T 类型的情况下获取 Task 的结果 [重复]

    这个问题在这里已经有答案了 我正在开发一个 C 系统 一个类有一个返回 a 的函数System Threading Tasks Task对象并具有属性System Type返回类型 当 ReturnType 为 null 时 我知道该方法返
  • Python 中的 MySQL 连接器不允许 LOAD DATA INFILE 语法

    我正在尝试将文本文件发送到 MySQL 数据库 我正在尝试使用 python 3 2 中的 mysql 连接器来执行此操作 问题与 LOAD DATA INFILE 语法有关 你可以在上面找到我的代码 我的第一个问题是有没有办法解决这个问题
  • Android:使用 Intent setResults 来回传递数据

    我正在为 Android 创建一个基于 GPS 的应用程序 有 2 个活动 Main 和 LocNames Main 显示我的地图 LocNames 是获取用户想要的源和目的地 我想在用户从菜单中选择 LocNames 时启动 LocNam
  • Tensorflow 2.0 和 Java API

    注意 我已经解决了我的问题并将代码发布在底部 我正在使用 TensorFlow 后端处理必须在 Java 中进行 我从 中取出了其中一个模型https developers google com machine learning crash
  • 如何为异步方法编写单元测试用例?

    我想通过模拟依赖项来编写单元测试用例 整体流程如下 我们有一个WorklistLoader它有一个异步方法LoadWorklistItemsAsync 为了完成这个任务WorklistLoader依赖于下层 API 我想模拟 QueryMa