使用.NET Moq时如何转发到另一个对象?

2023-12-27

给定一个对象,我想创建一个模拟,它实现该对象的接口并模拟一个方法,但将其余方法转发给真实对象,不是基类.

例如:

ISqlUtil sqlUtil = GetTheRealSqlUtilObjectSomehow(...);
var mock = new Mock<ISqlUtil>();
mock.Setup(o => o.SpecialMethodToBeMocked(...)).Returns<...>(...)
// Here I would like to delegate the rest of the methods to the real sqlUtil object. How ?

所以,在这个例子中我想模拟ISqlUtil.SpecialMethodToBeMocked并将其余方法/属性转发到现有实例sqlUtil.

在 Moq.NET 中可能吗?

EDIT 1

它也应该适用于通用方法。


开箱即用的 Moq 无法做到这一点。然而,我认为如果你深入到下一层并直接使用 Castle DynamicProxy (这是 Moq 下面的),你基本上可以实现你想要的。

因此,给出以下基本代码来模拟您的问题(本质上是一个接口、一个具体实现和一个工厂,因为具体很难制作/设置):

public interface ISqlUtil {
    T SomeGenericMethod<T>(T args);

    int SomeMethodToIntercept();
}
public class ConcreteSqlUtil : ISqlUtil {
    public T SomeGenericMethod<T>(T args){
        return args;
    }
    public int SomeMethodToIntercept() {
        return 42;
    }
}
public class SqlUtilFactory {
    public static ISqlUtil CreateSqlUtil() {
        var rVal = new ConcreteSqlUtil();
        // Some Complex setup
        return rVal;
    }
}

然后您可以进行以下测试:

public void TestCanInterceptMethods() {
    // Create a concrete instance, using the factory
    var coreInstance = SqlUtilFactory.CreateSqlUtil();

    // Test that the concrete instance works
    Assert.AreEqual(42, coreInstance.SomeMethodToIntercept());
    Assert.AreEqual(40, coreInstance.SomeGenericMethod(40));

    // Create a proxy generator (you'll probably want to put this
    // somewhere static so that it's caching works if you use it)
    var generator = new Castle.DynamicProxy.ProxyGenerator();

    // Use the proxy to generate a new class that implements ISqlUtil
    // Note the concrete instance is passed into the construction
    // As is an instance of MethodInterceptor (see below)
    var proxy = generator.CreateInterfaceProxyWithTarget<ISqlUtil>(coreInstance, 
                                new MethodInterceptor<int>("SomeMethodToIntercept", 33));

    // Check that calling via the proxy still delegates to existing 
    // generic method
    Assert.AreEqual(45, proxy.SomeGenericMethod(45));
    // Check that calling via the proxy returns the result we've specified
    // for our intercepted method
    Assert.AreEqual(33, proxy.SomeMethodToIntercept());
}

方法拦截器如下所示:

public class MethodInterceptor<T> : Castle.DynamicProxy.IInterceptor {
    private T _returns;
    private string _methodName;
    public MethodInterceptor(string methodName, T returns) {
        _returns = returns;
        _methodName = methodName;
    }
    public void Intercept(IInvocation invocation) {
        if (invocation.Method.Name == _methodName) {
            invocation.ReturnValue = _returns;
        }
        else {
            invocation.Proceed();
        }
    }
}

本质上,拦截器检查正在调用的方法是否与您感兴趣的方法匹配,如果是,则返回存储的返回值。否则,它会调用Proceed,它将方法调用委托给创建代理时提供的具体对象。

示例代码使用字符串而不是 lambda 来指定要拦截的方法,显然这可以更改(供读者练习)。另外,这没有使用起订量,所以你会失去Setup, Returns and Verify元素,它们被拦截器取代,因此这可能与您想要的有用的东西相距太远,但是根据您的代码的实际情况,它可能是一种可行的替代方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用.NET Moq时如何转发到另一个对象? 的相关文章

  • C 语言的符号表

    我目前正在开发一种执行模式匹配的静态分析工具 我在用Flex https github com westes flex生成词法分析器 我编写了代码来管理符号表 我不太有经验C 所以我决定将符号表实现为线性链表 include
  • 如何将 int.TryParse 与可为空的 int 一起使用? [复制]

    这个问题在这里已经有答案了 我正在尝试使用 TryParse 来查找字符串值是否为整数 如果该值为整数 则跳过 foreach 循环 这是我的代码 string strValue 42 if int TryParse trim strVal
  • 尽管 if 语句,Visual Studio 仍尝试包含 Linux 标头

    我正在尝试创建一个强大的头文件 无需更改即可在 Windows 和 Linux 上进行编译 为此 我的包含内容中有一个 if 语句 如下所示 if defined WINDOWS include
  • tmpnam 的 C/C++ 线程安全性?

    我需要使用tmpnamC 中的函数 但我需要了解它的线程安全性 也就是说 如果我有多个线程 每个线程都需要为临时文件获取不同的名称 我是否可以保证每个线程都会收到具有不同名称的文件 tmpnam 仅保证该文件当时不存在 但它可能会在您自己创
  • 计算序列而无法存储值?

    问题陈述 here http www spoj com problems EC SER 令 S 为无限整数序列 S0 a S1 b Si Si 2 Si 1 对于所有 i gt 2 你有两个整数 a 和 b 您必须回答有关序列中第 n 个元
  • 表达式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 错误

    此错误发生在运行时 我不确定是什么原因导致的 代码对我来说看起来是正确的 include
  • 清理 STL 指针列表/向量

    您可以想出的最短的 C 块是多少来安全地清理std vector or std list指针 假设您必须对指针调用删除 list
  • esp8266互联网交换机问题

    我正在尝试制作一个门继电器开关系统 我可以通过端口转发从任何地方进行操作 我找到了一个非常有用的指南和代码 我的程序基于 https openhomeautomation net control a lamp remotely using
  • 如何在提升日期时间中忽略周末和节假日?

    第一个问题 我有一个提升日期对象 如下所示 boost gregorian date 今天 2012 02 13 我从今天减去日期部分 如下所示 今天 月 240 或今天 天 X 等 我想在进行上述减法时是否有办法排除周末和特殊假期 我的意
  • 使用迭代器遍历 boost::ublas 矩阵

    我只是想从头到尾遍历一个矩阵 触及每个元素 然而 我发现升压矩阵没有一个迭代器 而是有两个迭代器 而且我无法弄清楚如何使它们工作以便您可以遍历整个矩阵 typedef boost numeric ublas matrix
  • c++ 最大 std::string 长度由堆栈大小或堆大小决定?

    正如问题中所问 std string myVar 它可以容纳的最大字符是由堆栈还是堆决定的 谢谢 默认情况下 分配的内存为std string是动态分配的 注意std string has a max size 函数返回实现支持的最大字符数
  • DirectX Vertex 中的 THE 是什么

    我知道 RHW 是倒数同质 W 但有人可以解释一下它的使用方法和作用吗 gamedev论坛上的说明post http www gamedev net topic 440283 reciprocal of homogeneous w and
  • 使用 C# 从文本中删除数字

    我有一个要处理的文本文件 其中有一些数字 我只想要其中的文字 而不是其他任何东西 我成功删除了标点符号 但是如何删除数字呢 我想要使 用 C 代码 另外 我想删除长度大于 10 的单词 如何使用 Reg 表达式来做到这一点 您可以使用正则表
  • try-catch 块是否会降低性能[重复]

    这个问题在这里已经有答案了 This link http www cplusplus com doc tutorial exceptions states 为了捕获异常 我们必须将一部分代码放在异常下 检查 这是通过将这部分代码包含在 tr
  • 以编程方式打开网页并以字符串形式检索其 html 包含内容

    我有一个 Facebook 帐户 我想提取我朋友的照片及其个人详细信息 例如 出生日期 就读学校 等 我能够提取我每个朋友帐户的 Facebook 首页的地址 但我不知道如何以编程方式打开我每个朋友首页的网页并将 html 包含保存为字符串
  • if(pointerVar) 与 if(pointerVar!=NULL) 相同吗?

    简单的问题 Is if pointerVar 与if pointerVar NULL 也是if pointerVar 与if pointerVar NULL 给我你在技术上最正确 迂腐的答案 这两种说法看起来和操作起来都是一样的 前者有什么
  • 如果未先将 lambda 表达式强制转换为委托或表达式树类型,则无法将其用作动态分派操作的参数

    我正在使用 NET4 5 和 VS2013 我有这个查询dynamic来自数据库的结果 dynamic topAgents this dataContext Sql select t create user id as User sum t
  • MSVC如何在编译期间输出一些内容到“输出”窗口

    有时我看到某些项目在编译期间向输出写入一些内容 在MSVC 中如何实现 thanks use pragma message e g define MESSAGE t message FILE STRINGXXX LINE t define
  • 隐藏 MediaPlayer 控件(Microsoft 媒体平台播放器框架)

    我在 c xaml 应用程序中使用 MMP PF 提供我自己的控制元素来处理播放器 这就是为什么我想隐藏 禁用出现在底部的本机控件 在屏幕截图的屏幕中间 这只是使用了一个主题 有人知道该怎么做吗 我没能找到合适的房产 像这样使用 axWin
  • C++ 中带逗号的表达式的执行顺序 [重复]

    这个问题在这里已经有答案了 我的理解是这个词j i将在之前执行 i在声明中 j i i C 标准是否保证j i将在之前执行 i在循环 for auto i std next begin j begin i end j i i 逗号运算符引入

随机推荐

  • PostgreSQL:有效的变量分配示例?

    看完之后这个问题 https stackoverflow com questions 2944297 postgresql function for last inserted id 我正在尝试将一些 SQL 从 MySQL 转换为 Pos
  • 在 WordPress 中向自定义帖子类型添加多个日期

    我正在构建一个包含页面 帖子和活动的 WordPress 网站 您可以登录多个日期 我是 WordPress 新手 所以我一直在寻找适合此事件的理想解决方案 我相信最好的解决方案是创建名为 事件 的自定义帖子类型 然后单独处理它 但我不确定
  • Twitter API - 403 禁止错误

    我有一个非常简单的代码片段 直到昨天才工作 今天停止工作了 var url http search twitter com search json q dogs callback var reddit http reddit com r t
  • 按因子水平对数据框进行子集化

    我有一个大数据框 其中一列中包含州名称 其他列中包含不同的索引 我想按状态进行子集化 并创建一个适合最小化索引或已给出计算的数据框的对象 这是我所拥有的一个简单 简短 示例 m x y 1 A 1 0 2 A 2 0 3 A 1 5 4 B
  • 在 REST API 中,什么时候我应该使用信封?如果我在一个地方使用它,我应该一直使用它吗?

    我正在致力于构建 RESTful Web 服务 我已经尽可能地阅读了每种机制使用 HTTP 的原理 并且大多数时候 比如在获取资源时 它都工作得很好 但是 当我需要发布某种新条目时 为了清晰和稳健 无论客户端可能做什么 我都想提供新条目可能
  • 在python中用字符串打印偶数字符

    s Abrakadabra for k in len s if k 2 1 print s k 这段代码不起作用 问题出在哪里 您正在尝试迭代 int len s 我认为你只是错过了range功能 s Abrakadabra for k i
  • NSTextFieldCell 垂直对齐,解决方案似乎挤压了水平对齐

    我有一个 NSTextFieldCell 我希望以中间垂直对齐方式显示 感谢这里的一个旧问题和一篇博客文章 我有两个可行的解决方案 然而 这两种解决方案似乎都削弱了我将单元格设置为右对齐的能力 谁能帮助我使这些解决方案中的任何一个都支持两种
  • JIRA:查找我上周记录的所有工作

    我如何创建一个 JIRA 过滤器来列出我遇到的所有问题 记录时间 然后我可以将其应用到活动流 通过 JQL 使用高级搜索 worklogAuthor currentUser AND worklogDate gt 2016 12 01 AND
  • 如何用python打开mp4文件?

    我试图制作一个使用默认 Windows 应用程序播放电影的脚本 但是当我尝试运行此脚本时 出现错误 强制转换为 Unicode 需要字符串或缓冲区 找到函数 我应该如何进行 import os print Push enter to pla
  • 使用 VBA 解析 JSON (Access 2010)

    我需要使用下面的 JSON 文件更新 MS Access 中的货币表 timestamp 1465843806 base CAD rates AED 2 87198141 AFN 54 21812828 ALL 95 86530071 AM
  • 如何向 Android 原生“编辑文本”上下文菜单添加选项

    是否可以将某些内容添加到用户长按任何编辑文本时显示的项目列表中 剪切 复制粘贴 选择文本 全选 输入法 我想在此菜单中添加另一个选项 但无法弄清楚 这个问题有重复的here https stackoverflow com questions
  • 如何防止用户更改系统日期/时间(在 Android 中)?

    我用谷歌搜索过 但我找不到任何建议来阻止用户更改 android 中的系统日期 时间 我们正在开发一个企业应用程序 我们希望阻止设备的用户能够设置时间设置 换句话说 我们想要设置一个策略来定义用户不能更改 Android 设备中的日期和时间
  • 安装的Python脚本无法导入包模块

    我创建了一个具有以下目录结构的 Python 包 LICENSE MANIFEST IN README rst VERSION docs multitool init py core init py classes py utils py
  • 从 Visual Studio 2017 在 Chrome 中调试网站时启用扩展

    从 Visual Studio 2015 切换到 2017 我发现启动 Web API 项目现在会启动一个干净 独立的 Chrome 窗口 在很大程度上我喜欢这样 而且我当然喜欢这个想法 但是 这也意味着Chrome 中缺少扩展程序 有没有
  • 限制 GWT 中的小数位数?

    在纯 Java 中 我通常会使用如下所示的函数来将小数位数限制为decimalCount对于给定的数字value 但是 根据 GWT 文档 GWT 不提供对日期和数字格式化类 例如 java text DateFormat java tex
  • 如何在Python 3.6中等待声音文件以vlc结尾

    我在 python 中的 vlc 有一个问题 import vlc sound vlc MediaPlayer sound mp3 sound play i wanna wait until the sound ends then do s
  • Java:没有 AtomicFloat 或 AtomicDouble 吗?

    我已经发现AtomicInteger AtomicLong 但是在哪里AtomicFloat or AtomicDouble 也许有什么技巧 API 文档为java util concurrent package http download
  • 在多租户数据库中索引 TenantID

    我正在为应用程序创建多租户数据库 我在每个表方法中都使用了 TenantID 效果非常好 我正处于性能调整阶段 我的问题是 每个表中的每个 TenantID 是否都应该建立索引以进行优化搜索 因为数据库上的每个查询都会在此列上进行过滤 期待
  • 在node.js中重新定义变量

    该脚本的执行 tmp js 其中包含 var parameters 1 eval var parameters a 1 1 eval console log parameters node tmp js 产生 如果我们注释掉第一条语句 并再
  • 使用.NET Moq时如何转发到另一个对象?

    给定一个对象 我想创建一个模拟 它实现该对象的接口并模拟一个方法 但将其余方法转发给真实对象 不是基类 例如 ISqlUtil sqlUtil GetTheRealSqlUtilObjectSomehow var mock new Mock