我有像
这样的方法public abstract class Base
{
public void MethodUnderTest();
}
public class ClassUnderTest : Base
{
public override MethodUnderTest()
{
if(condition)
{
IMail mail = new Mail() { /* ... */ };
IMailer mailer = new Mailer() { /* ... */ }
mailer.Send(mail);
}
else
{
/* ... */
}
}
}
我有这个方法的单元测试,邮件被发送给我自己,所以它并不可怕(比没有测试更好),但我不想发送邮件。
我还能做什么?
(注意:IMail和IMailer是发送电子邮件的外部库的一部分。它是内部编写的,所以我可以根据需要修改它,尽管在这种情况下我看不到需要)
答案 0 :(得分:7)
使用依赖注入的标准方法是在IMailer
的构造函数中需要ClassUnderTests
。如果你这样做,你将模拟邮件传递给你的测试,基类不需要知道关于邮件或邮件的任何信息。
如果出于某些原因这是不合需要的(这种情况非常罕见,通常只在你不控制底层类时才有意义),你可以使用setter injection(“属性注入”)。
答案 1 :(得分:2)
您(可以)可以使用取件目录并将其设置为未配置为发送的目录:
答案 2 :(得分:2)
您可以设置一个非常简单的虚假SMTP服务器,该服务器足以验证客户端是否发送了电子邮件。
答案 3 :(得分:1)
我会做这样的事情(考虑到你没有DI框架):
public class ClassUnderTest : Base
{
private IMail mail;
private IMailer mailer
public ClassUnderTest()
{
mail = new Mail() { /* ... */ };
mailer = new Mailer() { /* ... */ }
}
public ClassUnderTest(IMail mail, IMailer mailer)
{
this.mail = mail;
this.mailer = mailer;
}
public override MethodUnderTest()
{
if(condition)
{
mailer.Send(mail);
}
else
{
/* ... */
}
}
}
然后在测试中,只需调用第二个构造函数,而不是默认构造函数。
答案 4 :(得分:0)
我的回答一般(我不知道C#)
我曾经需要在Java中制作这样的东西。我做了测试以检查发送端口是否打开然后这意味着它几乎完成了。我强行停止这个过程。
答案 5 :(得分:0)
您可以截取通话以在多个级别发送邮件,但您仍然必须在某处拦截它,或忍受接收电子邮件。
这可能是:
拿出测试电子邮件。
添加一个电子邮件过滤器,用于删除电子邮件或将其存储在其他文件夹中,以免他们打扰您。
将测试电子邮件发送到其他电子邮件地址。将您的服务器设置为仅在收到时删除这些电子邮件(或将其保留14天,如垃圾邮件,以便您可以根据需要进行审核)。
将您的电子邮件服务器替换为虚假的本地服务器
将IMailer的imailer.dll或IMailer实现类替换为整个模拟等效项,或者使用一个不能实现完整SendMail行为的程序。
向SendMail()添加基类方法,并在运行单元测试时禁用其在基类中的行为。
在ClassUnderTest中添加一个虚拟的SendMail()方法,然后创建一个派生的类进行单元测试,它只是用模拟的实现覆盖SendMail()。
传入用于调用SendMail的接口/对象
传入一个标记以指示是否正在测试。
完全重新设计类,使其具有SendReport(),并且可以通过电子邮件,TCP / IP,日志文件等发送报告。
等
当然,最好的方法不需要更改正在测试的实际方法。选择最适合您情况的那个,以及您需要为此课程添加的其他单元测试。