我有一个第三方组件,我正试图围绕它编写单元测试。问题是我不能模拟对象,而且没有接口。
我决定创建一个接口和一个包装类来调用代码,以进行嘲讽。我查看了Visual Studio使用元数据生成的类定义,并注意到了以下几点:
- 该类有两个构造函数(其中一个接受参数)
- 该类继承自IDisposable
我的问题是:
- 我下面的实现看起来正确吗
- 我是否在代理类中正确处理了IDisposable实现
- 由于接口不支持构造函数定义,我是否需要代理类中的第二个构造函数?我在代码中使用依赖注入,我认为除非我告诉我的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容器中出现奇怪的构造函数逻辑,请尝试将构造与初始化分离,并将后者包含在接口中。