我有一个读取pop3电子邮件服务器的类。我想为包含的类编写一些单元测试,因此我需要模拟POP3服务器类。我正在使用OpenPOP.Net。所以我有一个像这样的构造函数:
EmailHost(string email, string password, string pop3Address, int port)
... etc....
然后,我有一个连接类:
private void Connect()
{
_pop3 = new Pop3Client();
etc...
因此,对Pop客户端的引用被埋在该类的胆量中。为了能够模拟它,我需要做一些时髦的事情,因为在Pop3Client上使EmailHost成为通用类,或者添加一些具有默认功能的功能来完成上述代码:
public EmailHost<PopClass>(...)
要么
public EmailHost(... params, Func popGenerate = () => new Pop3Client())
因此,似乎我必须对我的构造函数进行一些折衷以使其能够与模拟一起使用。 (显然,我会定义一个IPop3Client等等。)
有关如何正确执行此操作的任何想法?
编辑:
jOk提供了一个有趣的答案,问题是它与我正在做的结构不完全匹配。在这种情况下,我需要在Pop客户端中处理多个电子邮件地址,并且这些地址是动态添加的。因此,在添加每个电子邮件地址时,需要创建一个新的Pop3Client。另外,我想隐藏POP3本身的实现,以使他们的用户不需要尽可能多地了解它。
还有其他想法吗?
感谢您输入顺便说一句。
最佳答案
我想你很亲密。
与其传入所有最终将用于创建Pop3Client实例的参数,不如考虑注入Pop3Client实例。
public EmailHost(IPop3Client client) {
}
这样,您将从创建Pop3Client对象的职责中删除了EmailHost类。而是将这种责任转移到其他地方,最常见的是转移到IoC容器。
从您发布的代码中我无法确定Pop3Client是否基于接口。如果很好,您可以在测试中对其进行模拟/存根并注入依赖项。如果没有,那么操纵它会涉及更多的工作,以便它可以在这种情况下工作。它可以像在类周围编写一个包装器(和相应的接口)那样简单,以暴露您在EmailHost内部使用的方法。然后可以在上面的示例中使用它代替IPop3Client。
那有意义吗?让我知道您是否需要更多指导。