我的任务是向一些预先存在的代码添加测试。我们试图将重构保持在最低限度,因此这些测试通常是单元/集成测试的组合。
我们也在这个项目上使用Moq,我正在学习这个项目。
我的问题是,如何使用Moq覆盖System.Configuration值(EmailFrom、EmailTo等)在下面的SendEmail中,所以我不必经常在所有测试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);
}发布于 2018-07-26 23:28:56
如何使用Moq覆盖System.Configuration值
莫克没有能力
重写System.Configuration值
备选案文1
在测试项目的app.config中设置值,因为这将是运行测试的上下文。
优点:无需重构代码。
缺点:必须在所有测试System.Configuration文件中不断地临时照看System.Configuration值。
选项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的类现在可以依赖于它的抽象,并在测试以确认SendEmail被调用时根据需要替换它。
https://stackoverflow.com/questions/51548297
复制相似问题