Moq - 是否可以在不使用 It.IsAny 的情况下设置模拟

2024-05-10

我一直使用 Moq 进行单元测试。有时我会嘲笑有很多参数的方法。

想象一下这样的方法:

public class WorkClient {

public void DoSomething(string itemName, 
   int itemCount, 
   ServiceClientCredential cred, 
   CancellationToken = default(CancellationToken){}
}

当我去设置模拟时,我最终不得不做很多事情It.IsAny<T>()。我通常为每个测试创建一个模拟实例,因此我不关心匹配参数。

但我的模拟仍然是这样的

var newMockClient = new Mock<WorkClient>();
newMockClient.Setup(x => x.DoSomething(
   It.IsAny<string>(), 
   It.IsAny<int>(),
   It.IsAny<ServiceClientCredential(),
   It.IsAny<CancellationToken>())
   .Returns(blah);

我希望能够懒惰地使用 LazySetup(如果存在),就像这样。

newMockClient.Setup(x=>x.DoSomething()).Returns(blah);

有没有这样的懒人模式?


基于此gist https://gist.github.com/christothes/7d57db1d16c96669ecd0218ab056a422你可以创建一个重载SetupDefaultArgs这适用于void返回类型。您需要添加对Moq.Language.Flow and System.Linq.Expressions;

public static ISetup<T> SetupDefaultArgs<T>(this Mock<T> mock, string methodName)
    where T : class
{
    var method = typeof(T).GetMethod(methodName);
    if (method == null)
        throw new ArgumentException($"No method named '{methodName}' exists on type '{typeof(T).Name}'");
            
    var instance = Expression.Parameter(typeof(T), "m");
    var callExp = Expression.Call(instance, method, method.GetParameters().Select(p => GenerateItIsAny(p.ParameterType)));
    var exp = Expression.Lambda<Action<T>>(callExp, instance);
    return mock.Setup(exp);
}

//helper method for above
private static MethodCallExpression GenerateItIsAny(Type T)
    {
        var ItIsAnyT = typeof(It)
            .GetMethod("IsAny")
            .MakeGenericMethod(T);
        return Expression.Call(ItIsAnyT);
    }

因此,在您的情况下,用法将如下所示:

public interface IWorkClient
{
    void DoSomething(string itemName, int itemCount,
        ServiceClientCredential cred,
        CancellationToken token = default(CancellationToken));
}
var mock = new Mock<IWorkClient>();
mock.SetupDefaultArgs(nameof(IWorkClient.DoSomething));

要确保它已被调用,您可以执行以下操作:

//Arrange
var mock = new Mock<IWorkClient>();
mock.SetupDefaultArgs(nameof(IWorkClient.DoSomething))
    .Callback(() => Console.WriteLine("DoSomething has been called"));

var cts = new CancellationTokenSource();

//Act       
mock.Object.DoSomething("1", 2, null, cts.Token);

//Assert
mock.Verify(client => client.DoSomething("1", 2, null, cts.Token), Times.Once);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Moq - 是否可以在不使用 It.IsAny 的情况下设置模拟 的相关文章

随机推荐

  • Matplotlib 将颜色图 tab20 更改为三种颜色

    Matplotlib 有一些新的且非常方便的颜色图 选项卡颜色图 https matplotlib org examples color colormaps reference html 我错过的是生成像 tab20b 或 tab20c 这
  • OVER ORDER BY 中的多个列

    有没有办法在 OVER ORDER BY 子句中指定多个列 SELECT ROW NUMBER OVER ORDER BY A Col1 AS ID FROM MyTable A 上面的方法工作正常 但尝试添加第二列不起作用 SELECT
  • 尝试在本地主机上测试我的 php 文件,但只出现一个空白页面,没有错误消息

    我正在运行 Apache 和 mySQL 因为我检查了所有日志 似乎没有任何错误 我的目标是每当有新的表单条目时就向特定地址发送电子邮件 我对后端和 PHP 缺乏经验 所以我不太确定哪里出了问题 任何帮助将不胜感激
  • 哪种 Java DOM 包装器是最好或最受欢迎的? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 使用脚本自动输入 SSH 密码

    我需要创建一个自动向 OpenSSH 输入密码的脚本ssh client 假设我需要通过 SSH 进入myname somehost用密码a1234b 我已经尝试过 bin myssh sh ssh myname somehost a123
  • 如何在高速缓存中存储图像

    我对此完全空白 我想从 URL 下载图像 并且必须将其存储在内部 以便下次我不需要连接到网络 而是从缓存中检索它 但我不知道该怎么做 谁能帮我提供一个代码片段 import java io BufferedInputStream impor
  • Python time.sleep - 永不醒来

    我认为这将是那些简单的问题之一 但它让我感到困惑 停止媒体 我是对的 找到了解决方案 查看答案 我正在使用 Python 的单元测试框架来测试多线程应用程序 很好而且很直接 我有 5 个左右的工作线程监视一个公共队列 以及一个为它们制作工作
  • 如何将reportlab与Google应用程序引擎一起使用

    我无法在谷歌应用程序引擎下正确导入reportlab 根据以下guide http blog notdot net 2010 04 Generating PDFs on App Engine Python and introducing M
  • useEffect 中的 useState 不更新状态

    我是 React Hooks 新手 正在使用 React 16 13 1 我要实施Auth能够处理登录的组件 但似乎没有更新状态currentUser正确地 尽管setCurrentUser使用响应对象调用 这段代码有什么问题 import
  • JavaScript:嵌套循环?

    我想实现这样的动画 序列 动画以循环开始 想象一下car从 x1 移动到 x2 然后暂停 1 秒 然后再次播放动画 想象一下car从 x2 移动到 x3 等 the car循环是通过向汽车左侧添加 1px 来实现的 值 但我无法弄清楚嵌套循
  • 无法使用数据源配置向导在 Web 项目中添加数据源

    Problem 我想将报告 rdlc 添加到我的 Web 项目中 我需要报表使用对象数据源 而不是直接连接到数据库 我的问题是 当我运行 报告向导 或向报告添加新数据集时 数据源配置向导 only允许我使用数据库 然而 在图书馆项目中数据源
  • C# 中不区分大小写的替换不使用正则表达式?

    有没有一种方法可以在不使用 C 中的正则表达式的情况下对字符串进行不区分大小写的替换 像这样的东西 string x Hello x x Replace hello hello world 你可以尝试类似的东西 string str Hel
  • 如何在IOS中使用“*”字符进行呼叫(拨号)?

    我希望用 字符来调用 例如 gt 711313 目前 我正在使用这段代码 NSString str NSString stringWithFormat tel tmp UIApplication sharedApplication open
  • 选择不带 FROM 但有多于一行的选择

    如何在不从现有表中进行选择的情况下生成 2 行 2 列的表 我正在寻找的是一个返回的选择语句 e g id value 1 103 2 556 Use UNION http dev mysql com doc refman 5 0 en u
  • scikit-learn RandomForestClassifier 中的子样本大小

    如何控制用于训练森林中每棵树的子样本的大小 根据 scikit learn 的文档 随机森林是一种适合许多决策的元估计器 数据集的各个子样本上的树分类器并使用 平均以提高预测准确性并控制过度拟合 子样本大小始终与原始输入样本相同 大小 但如
  • Spring Boot中使用自定义令牌进行身份验证

    我需要保护我的 Spring Boot 应用程序 这就是我所拥有的 一个 Spring Boot 应用程序 公开了一些 REST API 与公开的 api 通信的前端 前端发送用于身份验证的自定义身份验证令牌 存储自定义身份验证令牌的数据库
  • postgreSQL 将分区表(带插入触发器)从一台服务器转储和恢复到另一台服务器

    尝试将分区表从一台服务器转储到 PostgreSQL 9 4 5 中的另一台服务器 对 postgres 相当陌生 并继承了该项目 如果需要更多背景信息 请告诉我 dbname gt SELECT COUNT id FROM parent
  • 使用数学符号注释 Adob​​e Reader PDF

    我阅读的许多数学教科书和其他文献都是 PDF 格式 因此我经常使用 Adob e Reader 注释工具对它们进行注释 我确实找到了一个有用的指南 http cjasn asnjournals org site misc annotatin
  • SQL:两个没有完整列匹配的表的并集

    我有一个table A其中有一组列A1 A2和一个具有一组列的 table bB1 B2 碰巧的是A2 B1但其余列不匹配 也不应该匹配 我想附加表格 所以我使用UNION ALL 对于不匹配的列 我使用null as COLUMN NAM
  • Moq - 是否可以在不使用 It.IsAny 的情况下设置模拟

    我一直使用 Moq 进行单元测试 有时我会嘲笑有很多参数的方法 想象一下这样的方法 public class WorkClient public void DoSomething string itemName int itemCount