我有一个void函数,它发送电子邮件。我需要为这个函数编写测试。怎么办呢?
public void SendAdminMail(string subject, string body, string adminAddress)
{
var email = Email.
From(ConfigurationManager.AppSettings["Mail.NoReply.Address"].ToString(CultureInfo.InvariantCulture)).
To(adminAddress).
Subject(subject).
Body(body).
UsingClient(GetOfficeClient());
email.Message.SubjectEncoding = Encoding.UTF8;
email.Message.BodyEncoding = Encoding.UTF8;
email.Send();
}
答案 0 :(得分:3)
在这种情况下,这将是非常困难的 - 除非你能够以某种方式通过反思切换Email
(正如juhan_h in his answer有趣地指出的那样,现在也许并不那么难;)。 / p>
典型的解决方案是为您的班级提供界面,例如interface EmailFactory
。然后你就有了:
private EmailFactory emailFactory;
public void SendAdminMail(string subject, string body, string adminAddress)
{
var email = emailFactory
.From(ConfigurationManager
.AppSettings["Mail.NoReply.Address"]
.ToString(CultureInfo.InvariantCulture))
.To(adminAddress)
.Subject(subject)
.Body(body)
.UsingClient(GetOfficeClient());
email.Message.SubjectEncoding = Encoding.UTF8;
email.Message.BodyEncoding = Encoding.UTF8;
email.Send();
}
然后你可以为你的班级提供这个工厂的存根,这将创建电子邮件模拟,你可以在其上验证正确的行为。
答案 1 :(得分:2)
如果您碰巧拥有Visual Studio 2012 Ultimate或Premium,那么您可以为System.Net.Mail
程序集生成Fakes程序集并使用它。
有关Fakes的更多信息,请访问MSDN。
如果您没有VS2012旗舰版或Premium版,那么我的答案是完全没用的。)
答案 2 :(得分:2)
我开始认为在拔下网络电缆时单元测试应该可行。
你真的想测试什么?
您可以使用模拟或伪造,并验证您已按预期调用方法。
能够将这个类存根并在别处使用存根以确保其余的测试在每次运行时都不发送电子邮件可能会更有用。
答案 3 :(得分:1)
如何做到这一点?
测试此方法并非直截了当,除非您使用某些库或框架来执行大量变通办法,因为您的方法违反了SRP原则。
虽然您的方法名为SendAmdinMail,但实际上只有一个语句处理发送,为email.Send()
,其余方法是使用.NET API构建邮件消息。
您应该将此方法分解为不同的部分,如CreateMailBody,CreateHeader,LoadMailConfig以及隐藏在抽象(接口,抽象类)后面发送的邮件,以便您可以创建邮件发送服务的模拟。 / p>
这样您还可以测试邮件正文的内容,可以测试收件人等。
答案 4 :(得分:1)
您想要写的是integration test而不是unit test。
如果你想测试你的代码调用一些负责发送电子邮件的函数,那么你想通过使用某种模拟框架来编写单元测试,例如NSubstitute。
[Test]
public void ShouldSendEmail()
{
IEmailService mockEmailService = Substitute.For<IEmailService>();
MyEmailSendingThingy thingUnderTest = new MyEmailSendingThingy(mockEmailService);
thingUnderTest.DoSomeWorkThatInvolvesSendingEmails();
mockEmailService.Received().SendEmail("foo@foo.foo", "bar@bar.bar", "Subject", "Some Text");
}
如果您想测试您的应用程序实际发送的电子邮件,您想要编写集成测试。您可以通过多种方式实现这一目标。
1和2需要付出很多努力,您必须考虑发送电子邮件的异步性质。这意味着您将不得不睡眠您的程序或使用某种触发器等待电子邮件到达目的地,应尽可能避免。
3我的个人选择有三个原因。您可以在测试过程中托管它,从而更容易进行断言。其次,它是可重用的,可以在任何测试框架中使用。第三,作为奖励,您可以更好地了解电子邮件的工作原理。
4就个人而言,我不喜欢嘲笑静态或具体的组件..它可能导致坏习惯和糟糕的代码。但是,使用正确方法的工具可能是一件有用的事情,这可能是您测试这部分代码的最佳方式。
最后确保您正在测试正确的事情。您不应该测试Microsoft是否正确编写了System.Email组件,您只需要确保正确调用组件