我应该如何测试从控制器发送电子邮件?

时间:2010-05-26 15:52:31

标签: asp.net-mvc unit-testing email dependency-injection

我开始进行单元测试并试图做一些TDD。我已经阅读了很多关于这个主题的内容,并写了一些测试。我只是想知道以下是否是正确的方法。

我想在我的网站上添加通常的“联系我们”设施。你知道的事情,用户用他们的电子邮件地址填写表格,输入一条简短的信息,然后按一个按钮发回表格。

模型绑定器执行它们的操作,我的操作方法接受发布的数据作为模型。然后,操作方法将解析模型并使用smtp向网站管理员发送电子邮件,让他/她填写有关人员在其网站上填写联系表单。

现在提出问题....为了测试这个问题,我是否会正确创建一个接口 IMessageService ,它具有方法发送(emailAddress,message)接受电子邮件地址和邮件正文。在具体类中实现接口,让该类处理smtp内容并实际发送邮件。

如果我将接口作为参数添加到我的控制器构造函数中,那么我可以使用DI和IoC将具体类注入控制器。但是在进行单元测试时,我可以创建我的 IMessageService 的假冒或模拟版本并对其进行断言。

我问的原因是我看过其他人为SmtpClient生成接口然后嘲笑它的例子。真的有必要走那么远,还是我不理解这些东西?

4 个答案:

答案 0 :(得分:2)

您仍然需要测试调用邮件程序的类。我建议你可能想要做两件事。我通常创建一个IMailClient接口和一个实现接口的SmtpClient包装器。在代理类中使用(并注入)接口,该代理类知道如何构造消息并将其发送(它可能有几个工厂类型的方法,可以构造多种不同类型的消息)。 SmtpClient周围的垫片应该就是这样,因此几乎不需要进行单元测试。您可以在测试代理类时模拟填充程序,并在测试控制器时模拟代理类。

答案 1 :(得分:1)

你描述的方法在过去对我有用。我参与了一个与MS Dynamics CRM Web服务API连接的项目。我想对我的代码进行单元测试,但我不想对Web服务进行单元测试。我按照您描述的确切过程,但使用Web服务进行模拟,而不是邮件传递。它工作得很好。

答案 2 :(得分:1)

你走在正确的轨道上,这就是你应该使用的方法。可能你所指的例子,是人们以艰难/错误的方式去做...或者是如何处理大型遗留代码库的例子。

注入传递消息的机制非常灵活,并且可以在其他场景中轻松重用。一个这样的场景是诊断,如果你有一个开发服务器,你可能不希望它一直打邮件,通过切换注入的类,你可以将它输出到一个文件或只是简单的Debug.Write。

PS。你仍然建议你测试你的SmptDeliver类,但这是一个集中的集成测试,你可以独立于其他代码在该类上进行。

答案 3 :(得分:1)

我认为你走在正确的轨道上。不要担心smtp服务器或其他任何东西。只需进行单元测试即可。让测试告诉你你需要什么。当您进行实际Send(emailAddress, message)的测试时,您可以担心如何将消息实际发送给管理员。