使用Moq覆盖C#测试中的系统配置值

使用Moq覆盖C#测试中的系统配置值,c#,automated-tests,moq,C#,Automated Tests,Moq,我的任务是向一些预先存在的代码中添加测试。我们试图将重构控制在最低限度,因此这些测试通常是单元/集成测试的组合 我们还在这个项目中使用Moq,我正在动态学习 我的问题是,如何使用Moq覆盖下面SendEmail中的System.Configuration值(EmailFrom、EmailTo等),这样我就不必在所有测试System.Configuration文件中不断监视System.Configuration值?我只是想测试一下我们是否执行Email.send代码 public cla

我的任务是向一些预先存在的代码中添加测试。我们试图将重构控制在最低限度,因此这些测试通常是单元/集成测试的组合

我们还在这个项目中使用Moq,我正在动态学习

我的问题是,如何使用Moq覆盖下面SendEmail中的System.Configuration值(EmailFrom、EmailTo等),这样我就不必在所有测试System.Configuration文件中不断监视System.Configuration值?我只是想测试一下我们是否执行Email.send代码

    public clas EmailLogging
    {
       public void SendEmail(string error}
            {
               string EmailFrom = System.Configuration.ConfigurationSettings.AppSettings["EmailFrom"].ToString();
               string EmailTo = System.Configuration.ConfigurationSettings.AppSettings["EmailTo"].ToString();
               string errorLogLocation = System.Configuration.ConfigurationSettings.AppSettings["ErrorLogLocation"].ToString();
               ...
               using (SmtpClient client = new SmtpClient())
                {
                   client.Send(mailMessage);
                }
如何使用Moq覆盖系统配置值

最低起订量没有能力

覆盖系统配置值

选择1

将测试项目的app.config中的值设置为运行测试的上下文

优点:无需重构代码

缺点:在我们所有的测试系统配置文件中,必须不断地监视系统配置值

选择2

重构代码,使其更加坚实,而不依赖于实现问题

public interface IConfigurationSettings {
    string AppSettings[string key] { get; }
}

public interface ISmtpClient: IDisposable {
    void Send(Message message);
}

public interface IEmailLogging  {
    void SendEmail(string error);
}

public class EmailLogging: IEmailLogging {
    private readonly IConfigurationSettings ConfigurationSettings;
    private readonly ISmtpClient client;

    public EmailLogging (IConfigurationSettings settings,  ISmtpClient client) {
        this.ConfigurationSettings = settings;
        this.client = client;
    }

    public void SendEmail(string error) {
       string EmailFrom = ConfigurationSettings.AppSettings["EmailFrom"];
       string EmailTo = ConfigurationSettings.AppSettings["EmailTo"];
       string errorLogLocation = ConfigurationSettings.AppSettings["ErrorLogLocation"];

       //...

       client.Send(mailMessage);            
    }
}
这将允许分离关注点,也允许在没有连锁效应的情况下单独测试单个实现

依赖于
EmailLogging
的类现在可以依赖于它的抽象,并在测试确认调用了
sendmail
时根据需要替换它