创建一个包装类以用于使用IDisposable的mocking



我有一个第三方组件,我正试图围绕它编写单元测试。问题是我不能模拟对象,而且没有接口。

我决定创建一个接口和一个包装类来调用代码,以进行嘲讽。我查看了Visual Studio使用元数据生成的类定义,并注意到了以下几点:

  • 该类有两个构造函数(其中一个接受参数)
  • 该类继承自IDisposable

我的问题是:

  1. 我下面的实现看起来正确吗
  2. 我是否在代理类中正确处理了IDisposable实现
  3. 由于接口不支持构造函数定义,我是否需要代理类中的第二个构造函数?我在代码中使用依赖注入,我认为除非我告诉我的DI框架使用第二个构造函数,否则我并不真正需要它,但我不确定

元数据看起来像(精简版):

public class PopClient : IDisposable
{
    public const int DefaultPort = 110;
    public const int DefaultSSLPort = 995;
    public PopClient();
    public PopClient(AddressFamily addressFamily);
    public bool HasTimeStamp { get; }
    public List<string> Capability();
    public void Connect(string host);
    protected override void GetServerGreeting();
}

基于元数据,我的接口看起来像(在删除接口定义中无效的方法/属性/访问修饰符之后):

public interface IPopClient : IDisposable
{
    bool HasTimeStamp { get; }
    List<string> Capability();
    void Connect(string host);
    void ConnectSSL(string host);
}

基于接口,我创建了包装器类:

public class PopClientProxy : IPopClient
{
    private readonly Pop3 pop3;
    public PopClientProxy()
        this.pop3 = new Pop3();
    public PopClientProxy(AddressFamily addressFamily)
        this.pop3 = new Pop3(addressFamily);
    public bool HasTimeStamp
        get { return pop3.HasTimeStamp; }
    public List<string> Capability()
        return pop3.Capability();
    public void Connect(string host)
        pop3.Connect(host);
    public void Dispose()
    {
        if (pop3 != null)
            pop3.Dispose();
    }
}

您的代理看起来不错。基于此,模拟测试所处理的接口的相关部分应该非常容易。

关于IDisposable实现,请查看一次性模式的常见实践。这个问题是关于它的。

对于构造函数,我认为它们根本不是接口的一部分,因此不需要在代理的实现中复制。如果这导致DI容器中出现奇怪的构造函数逻辑,请尝试将构造与初始化分离,并将后者包含在接口中。

最新更新