c# - 使用包装器类模拟 .NET 类

标签 c# .net unit-testing

我有一个类接受 MethodInfo 实例并从中提取一些信息,但我想模拟这个类。目前很难,因为它需要一个 MethodInfo,所以我的计划是为 MethodInfo 类创建一个包装器并在其上实现一个接口(interface)。例如:

public interface IMethodInfo
{
    string Name { get; }
}

public class MethodInfoProxy : IMethodInfo
{
    private readonly MethodInfo _method;
    public MethodInfoProxy(MethodInfo method)
    {
        _method = method;
    }

    public string Name { get { return _method.Name; } }
}

public class MyClass
{
    public MyClass(IMethodInfo method)
    {
        ...
    }
}

另一个例子是 File.Exists 方法。我们的想法是创建一个 IFile.Exists 并将其放在一个 FileProxy 类上,该类将简单地委托(delegate)给 File.Exists。

由于我是整个单元测试领域的新手,所以我想知道这是否是一种好的方法?

最佳答案

这里有两个选择:

  1. 使用类似 Microsoft Moles 的模拟框架或 TypeMock Isolator可以模拟静态和密封类。这很棒,因为您最终不会仅仅为了将被测代码与其依赖项隔离而更改代码。
  2. 为您想要模拟的行为定义接口(interface),然后创建包装静态调用或其他难以测试的 API 的默认实现。这是您建议的方法,也是我经常使用的方法。关键是,在定义这些接口(interface)时,通过某种形式将接口(interface)的真实/模拟实现传递到测试类中 dependency injection - 通常是构造函数注入(inject)。有些人错误地在被测试的类中构造对象,这使得无法测试。一个好的经验法则是,当您看到在您的业务代码中构造对象时,那就是代码味道——并不总是坏事,但绝对值得怀疑。关于这个东西有一个很棒的视频:The Clean Code Talks - "Global State and Singletons" .

那些认为测试不应该改变代码的人和那些认为应该改变代码的人之间存在着一场宗教 war 。如果您要通过创建接口(interface)进行模拟,依赖注入(inject)是必不可少的,它会导致代码具有高内聚和松散耦合以及直观的 API。但其他方法并没有排除这些好处 - 它只是不那么自动。

关于c# - 使用包装器类模拟 .NET 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5447672/

相关文章:

c# - 附加到其他 PDF 文件后无法删除 PDF 文件 - C# - ItextSharp

c# - 即使在派生类中,基类方法也能返回 this 吗?

c# - 由于错误而无法删除临时文件

unit-testing - 具有注入(inject)服务的单元测试抽象类

c# - Moneris 半集成解决方案不工作

c# - 为构造函数类指定固定值和容器中的其他变量

c# - 秒表的数据绑定(bind)问题已过去

c# - 尝试读取或写入 protected 内存

visual-studio - 如何解决此错误 : vstest.executionengine.x86.exe 已停止工作?

python - 如何在模拟类的对象上定义任意属性?