单元测试:绕过或模拟调用静态电子邮件助手

时间:2015-06-17 09:24:46

标签: c# unit-testing

道歉 - 这可能是重复的。但我无法在网站的其他地方找到有用的答案。

目前正致力于向应用程序添加电子邮件发送功能。它不是在TDD下完成的,但我们在进行测试时已经建立了测试并且具有良好的覆盖率。

我的任务是将电子邮件调度添加到现有功能。

public ActionResult RequestApproval(int? id)
{
    Job job = rep.GetJob(id);
    //widgets

    job.IsApproved = true;
    SaveJob(job);
}

这是通过静态助手类完成的:

public static class EmailHelper
{
    public static void SendEmail(string subject, string body, params string[] to)
    {
         //gubbins
    }
 }

所以我正在添加

EmailHelper.SendEmail("Approval", "Please approve a thing", job.UsersWhoCanApprove.Select(a => a.Email).ToArray());

到RequestApproval函数。

我知道我可以通过摆弄配置来有效地测试电子邮件传递功能,但我不想在这里这样做。在第一个例子中,它很慢,在第二个例子中,测试属于静态类的测试套件。

不允许将接口放在静态类上。那么我该如何重构这个呢?我可以嘲笑或绕过对静态类的调用?

1 个答案:

答案 0 :(得分:5)

只需创建一个界面和一个实现:

public interface IEmailService
{
    void SendEmail(string subject, string body, params string[] to);
}

public class EmailService : IEmailService
{
    public void SendEmail(string subject, string body, params string[] to)
    {
         //gubbins
    }
 }

然后,如果您针对接口进行编程,例如构造函数注入实际实现,您可以使用模拟框架轻松地在测试中模拟此电子邮件服务,或者只是创建电子邮件服务的虚拟实现。当然,在您的真实逻辑中,您使用真正的EmailService实现。

实际上,您很少需要在代码中使用真正的静态类(除非您有扩展方法等)。如果您注入这样的实例并针对接口进行编程,它就会更加灵活和模块化。