使用包装类模拟.NET类

Mot*_*oSV 5 .net c# unit-testing

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

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)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

另一个例子是File.Exists方法.我们的想法是创建一个IFile.Exists并将它放在一个FileProxy类上,该类只需委托给File.Exists.

由于我是整个单元测试世界的新手,我想知道这是不是一个好的方法?

she*_*tie 3

您在这里有两个选择:

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

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