混合使用同一类中的已实现方法和模拟方法

2023-12-02

我试图模拟类的某些方法,同时保留其他方法的真实实现。

现在,我确实在 stackoverflow 上找到了相关内容here。但是,所有建议的答案都没有帮助我。

在大多数情况下,Lee 的答案可能很好,但在我的情况下是不合适的,因为我确实需要模拟一个接口(它有各种实现)而不是类本身。

布兰登的答案非常接近,但我发现了以下问题。
为了方便起见,粘贴了他的代码:

var mock = new Mock<ITestClass>(); // Create Mock of interface

// Create instance of ITestClass implementation you want to use
var inst = new ActualTestClass();

// Setup to call method of an actual instance
// if method returns void use mock.Setup(...).Callback(...)
mock.Setup(m => m.SomeMethod(It.IsAny<int>())
    .Returns((int x) => inst.SomeMethod(x));

导致我出现问题的是,这个示例适用于简单的场景,但如果“SomeMethod()”调用 ITestClass 中具有模拟设置的另一个方法,则它将不起作用。在这种情况下,“SomeMethod()”仍将使用真正的实现。

为了清楚起见:
假设 ITestClass 实现了方法 SomeMethod 和 SomeOtherMethod。前者必须调用后者,后者被嘲笑为:

mock.Setup(m => m.SomeOtherMethod(It.IsAny<bool>())
     .Returns(true);

现在 SomeMethod 如何使用这个模拟而不是真正的实现呢?

EDIT

我需要模拟接口而不是类本身的另一个原因是,如果 TestClass() 是单例,则后一个选项将不允许您测试 TestClass() 。


Moq、NSubstitute 或 FakeItEasy 等流行的隔离框架是受约束的。不可能用他们解决你的问题。

还有不受约束的隔离框架:TypeMock、JustMock(两者都是付费的)和 MS Fakes(仅在 VS Enterprise 中可用)。

然而,我最近发现了一个有趣的免费Pose库将解决您的问题。

Add package.

打开命名空间:

using Pose;

测试代码:

var inst = new ActualTestClass();

Shim testClassShim = Shim.Replace(() => inst.SomeOtherMethod(Is.A<bool>()))
    .With((ActualTestClass _, bool b) => true);

int actual = 0;

PoseContext.Isolate(() =>
{
    actual = inst.SomeMethod(1); // it will use shim inside
},
testClassShim);

Assert.Equal(0, actual);

但它在很多方面仍然比商业同行逊色很多。

应该指出的是,不受约束的工具虽然非常有效地解决了隔离问题,但通过这种方式它们会原谅设计错误,从而最终导致糟糕的应用程序架构。

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

混合使用同一类中的已实现方法和模拟方法 的相关文章

  • 强制 const 存储返回的值 value

    这就是我想要实现的目标 struct test const test returnconst return test test returnnonconst return test int main test t1 returnnoncon
  • 如何在运行 ASP.NET 页面时以编程方式设置表格背景?

    我有一个 aspx 页面 其默认背景颜色是一种 当选择单选按钮的某个选项时 我需要能够以编程方式更改它 我尝试设置表的 ID 字段 但似乎无法在 C 代码隐藏文件中访问它 我原来的表是 table style width 100 backg
  • 管理多个解决方案中存在的 C# 项目的 Nuget 包

    我现在正处于这样的阶段重构疯狂一个有很多的大项目遗留和不稳定的模块 我决定拆分解决方案目前 所有项目 大约有 20 个 而且由于下个月肯定会出现单元测试项目 还会有更多 链接在一起 使其更加独立和细化 通过这种方法 有一些模块 例如需要在多
  • iPhone 编程游戏

    使用 Objective C 还是 C 为 iPhone 编写游戏最好 像 Flight Control 这样的游戏会用什么语言编写 图形应采用什么格式才能在 iPhone 上正确显示并快速加载 像 Flight Control 这样的游戏
  • 如何使用 Regsvr32 注册 .NET COM DLL?

    我有一个使用 COM DLL 的 VB6 应用程序 该DLL是用C 编写的 在 C 项目属性中 我检查了 Register for COM interop 选项 VB6 应用程序在我的开发机器上运行良好 C 代码完全遵循以下格式 CodeP
  • 类型定义存在于两个库中

    我正在使用 NET 4 5 构建 ASP NET Web 窗体网站 错误 The type System ComponentModel DataAnnotations Schema ForeignKeyAttribute exists in
  • C# - 如何从 Steam 交易 API 获取图标的 URL(编码)

    以下是 API 为每个项目返回的 XML 部分
  • 带有 Prism 区域适配器的 AvalonDock

    我看到了一些关于 SO 的问题 但似乎没有一个适合我 我希望能够使用伟大的使用 Prism 4 但是 所有示例区域适配器均适用于 Avalondock 1 x 系列 我无法使其工作 有人有关于如何为 AvalonDock 的 LayoutD
  • 将控制台输入和输出重定向到文本框

    您好 提前致谢 我正在尝试 非常努力 将控制台输入和输出重定向到文本框 到目前为止 输出工作正常 但问题在于输入 例如 我无法执行一个简单的程序来执行以下操作 Console WriteLine 请输入您的姓名 字符串名称 Console
  • 使用 openssl 库获取 x509 证书哈希

    我目前正在开发一个应用程序 它使用 openssl 库 libcrypto 来生成证书 现在我必须获取现有证书的哈希值 当我使用终端时 我可以使用以下命令生成哈希值 openssl x509 hash in cert pem noout 输
  • 给出对象的指针作为参数

    假设我有 void func foo obj 我有 foo object 我该如何制作object进入争论func 只需取消引用它即可 func object
  • OpenCV:处理每一帧

    我想使用 OpenCV 编写一个跨平台应用程序进行视频捕获 在所有示例中 我发现来自相机的帧是使用抓取功能进行处理并等待一段时间 我想处理序列中的每一帧 我想定义自己的回调函数 每次当一个新帧准备好处理时都会执行该函数 例如直播对于 Win
  • 创建 PING 程序时限制 ICMP 回显答复

    我正在编写一个多线程 ping 程序 我在每个线程 针对每个 IP 上创建了原始套接字 并使用 sendto 向每个线程发送了 ICMP Echo 请求 然后在每个线程中执行了 receivevfrom 我正在从各种套接字中的 IP 获取消
  • 等效

    这是否保证始终为真 std numeric limits
  • 我使用 tm/mktime 是否错误,如果没有,有解决方法吗?

    我认为下面的程序应该输出从公元 1 年到 1970 年每年第一天到 1970 年的秒数 前面是time t在编译它的系统上 CHAR BIT是一个宏 所以我认为你不能只是复制编译后的可执行文件并假设它是正确的 尽管实际上一切都使用 8 位c
  • 在 4.x 内核上的 64 位内存中查找系统调用表

    我正在尝试编写一个简单的内核模块来查找 Linux 中的 sys call table 但遇到了一些麻烦 我在这里找到了 32 位 Linux 的基本指南 https memset wordpress com 2011 03 18 sysc
  • 对嵌套属性使用 XmlAttributeOverrides

    我试图使用 XmlAttributeOverrides 来控制类序列化后哪些类属性出现在 xml 中 它适用于 根 类上的属性 但不适用于嵌套属性 这是一个简单的例子来说明我想要完成的任务 我的类层次结构如下 public class Ma
  • 所有区域的启用保护模式必须设置为相同的值(启用或禁用)

    我正在尝试使用Selenium Internet Explorer驱动程序 但当我尝试实例化它时它崩溃了 TestInitialize public void TestInitialise ieDriver new InternetExpl
  • 将 Web 场迁移到 ASP.NET 运行时版本 4,同时保持会话

    我们已将 Web 应用程序从 net 运行时 2 v 3 5 迁移到 net 运行时 4 v 4 5 我有一个部署问题 我们的 sessionstate 服务器是一个 stateserver 并在单独的服务器上运行框架 2 中的 aspne
  • 如何获取打印机设备上下文?

    我在 Windows 上尝试使用以下命令打印增强型图元文件 EMF 播放增强元文件 http msdn microsoft com en us library dd162800 28VS 85 29 aspx 我当前正在使用屏幕上窗口的设备

随机推荐