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

C# 单元测试:绕过或模拟对静态电子邮件助手的调用,c#,unit-testing,C#,Unit Testing,抱歉-这可能是重复的。但我在网站的其他地方找不到有用的答案 目前正在向应用程序添加电子邮件发送功能。这不是在TDD下完成的,但我们已经在进行过程中构建了测试,并且具有良好的覆盖率 我的任务包括向现有功能添加电子邮件发送 public ActionResult RequestApproval(int? id) { Job job = rep.GetJob(id); //widgets job.IsApproved = true; SaveJob(job); }

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

目前正在向应用程序添加电子邮件发送功能。这不是在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功能

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


不允许在静态类上放置接口。那么,我如何将其重构为可以模拟或绕过对静态类的调用呢?

只需创建一个接口和一个实现:

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实现


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

只需创建一个接口和一个实现:

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实现


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

将邮件功能封装在接口后面,并针对接口编程。在测试模拟期间,对于您正在运行的系统,请使用使用静态EmailHelper类的接口实例将邮件功能封装在接口后面,并针对接口编写程序。在测试模拟期间,对于您正在运行的系统,使用使用静态EmailHelper类的接口实例希望避免这种情况,因为该helper类在其他地方使用。但鉴于没有其他人提出任何替代方案,我想我还有几天的重构时间:)但值得一试,因为这将改进代码并使其更易于测试:)希望避免这种情况,因为helper类在其他地方使用。但鉴于没有其他人提出任何替代方案,我想我还有几天的重构时间:)但这是值得的,因为它将改进您的代码并使其更易于测试:)