C# 如果我为一个email类创建一个Mock,它会发送一封真正的email吗?
从理论角度来看,这是一个简单的问题。如果我有C# 如果我为一个email类创建一个Mock,它会发送一封真正的email吗?,c#,.net,unit-testing,moq,C#,.net,Unit Testing,Moq,从理论角度来看,这是一个简单的问题。如果我有Email类,里面有Send()方法,负责发送电子邮件Send()方法在名为IEmail的接口中声明。让我们假设在我的单元测试中,我将moq该方法作为IEmail接口。然后,当我使用Send()设置moq,然后使用Verify()方法时,我假设不会发送真正的电子邮件,而只检查是否正确调用了Send()方法。我说得对吗?其次,要检查realSend()要真正发送电子邮件,我应该使用集成测试。这一切都正确吗?您可能测试的不是实际的电子邮件类。如果它是一个发
Email
类,里面有Send()
方法,负责发送电子邮件Send()
方法在名为IEmail
的接口中声明。让我们假设在我的单元测试中,我将moq
该方法作为IEmail
接口。然后,当我使用Send()
设置moq,然后使用Verify()
方法时,我假设不会发送真正的电子邮件,而只检查是否正确调用了Send()
方法。我说得对吗?其次,要检查realSend()
要真正发送电子邮件,我应该使用集成测试。这一切都正确吗?您可能测试的不是实际的电子邮件类。如果它是一个发送电子邮件的具体类,那么调用Send
将(而且可能应该)发送电子邮件
模拟对于测试依赖于IEmail
接口的类很有用。它允许您验证您的类对它所依赖的接口执行预期的操作。那样的话,你就不想发电子邮件了。您只需要测试您的类是否告诉IEmail
发送电子邮件
public class ClassThatSendsEmail
{
private readonly IEmail _email;
public ClassThatSendsEmail(IEmail email)
{
_email = email;
}
public void DoSomethingThatCausesAnEmailToGetSent()
{
var message = new Message {To = "bob@bob.com", Body = "Hi, Bob!"};
_email.Send(message);
}
}
下面是一个人工设计的类示例,它依赖IEmail
接口发送电子邮件
public class ClassThatSendsEmail
{
private readonly IEmail _email;
public ClassThatSendsEmail(IEmail email)
{
_email = email;
}
public void DoSomethingThatCausesAnEmailToGetSent()
{
var message = new Message {To = "bob@bob.com", Body = "Hi, Bob!"};
_email.Send(message);
}
}
…以下是我为测试而收集的一些其他类型:
public interface IEmail
{
void Send(Message message);
}
public class Message
{
public string To { get; set; }
public string Body { get; set; }
}
下面是一个非常简单的测试,它将模拟IEmail
public class Tests
{
[TestCase]
public void MyClassSendsAnEmail()
{
var emailMock = new Mock<IEmail>();
emailMock.Setup(x=>x.Send(It.IsAny<Message>())).Verifiable();
var subject = new ClassThatSendsEmail(emailMock.Object);
subject.DoSomethingThatCausesAnEmailToGetSent();
emailMock.Verify(x=>x.Send(It.IsAny<Message>()));
}
}
现在,您可以轻松编写一个测试,验证是否调用了IEmail.Send
,以及是否发送了预期的消息:
[TestCase]
public void MyClassSendsAnEmail()
{
var email = new EmailListDouble();
var subject = new ClassThatSendsEmail(email);
subject.DoSomethingThatCausesAnEmailToGetSent();
Assert.True(email.Any(message=> message.To == "bob@bob.com" && message.Body.Contains("Bob")));
}
Moq很好,但有时设置不仅会变得有点麻烦,而且会使测试内容更难确定。有时,只需使用双重测试就可以完成任务,而且更容易。您可能测试的不是实际的电子邮件类。如果它是一个发送电子邮件的具体类,那么调用Send
将(而且可能应该)发送电子邮件
模拟对于测试依赖于IEmail
接口的类很有用。它允许您验证您的类对它所依赖的接口执行预期的操作。那样的话,你就不想发电子邮件了。您只需要测试您的类是否告诉IEmail
发送电子邮件
public class ClassThatSendsEmail
{
private readonly IEmail _email;
public ClassThatSendsEmail(IEmail email)
{
_email = email;
}
public void DoSomethingThatCausesAnEmailToGetSent()
{
var message = new Message {To = "bob@bob.com", Body = "Hi, Bob!"};
_email.Send(message);
}
}
下面是一个人工设计的类示例,它依赖IEmail
接口发送电子邮件
public class ClassThatSendsEmail
{
private readonly IEmail _email;
public ClassThatSendsEmail(IEmail email)
{
_email = email;
}
public void DoSomethingThatCausesAnEmailToGetSent()
{
var message = new Message {To = "bob@bob.com", Body = "Hi, Bob!"};
_email.Send(message);
}
}
…以下是我为测试而收集的一些其他类型:
public interface IEmail
{
void Send(Message message);
}
public class Message
{
public string To { get; set; }
public string Body { get; set; }
}
下面是一个非常简单的测试,它将模拟IEmail
public class Tests
{
[TestCase]
public void MyClassSendsAnEmail()
{
var emailMock = new Mock<IEmail>();
emailMock.Setup(x=>x.Send(It.IsAny<Message>())).Verifiable();
var subject = new ClassThatSendsEmail(emailMock.Object);
subject.DoSomethingThatCausesAnEmailToGetSent();
emailMock.Verify(x=>x.Send(It.IsAny<Message>()));
}
}
现在,您可以轻松编写一个测试,验证是否调用了IEmail.Send
,以及是否发送了预期的消息:
[TestCase]
public void MyClassSendsAnEmail()
{
var email = new EmailListDouble();
var subject = new ClassThatSendsEmail(email);
subject.DoSomethingThatCausesAnEmailToGetSent();
Assert.True(email.Any(message=> message.To == "bob@bob.com" && message.Body.Contains("Bob")));
}
Moq很好,但有时设置不仅会变得有点麻烦,而且会使测试内容更难确定。有时候,只需使用双重测试就可以完成任务,而且更简单。moq
生成的方法除了跟踪调用的方法外,什么也做不了。是的,您是正确的。moq
生成的方法除了跟踪调用的方法外,什么也做不了。是的,您是正确的。集成测试看起来是什么样子,你能在此基础上给出一些例子吗?在你的第二次测试中,真正的电子邮件将被发送,因为我没有看到moq?那么这更像是集成测试吗?我在谷歌上搜索并发现了这个,我从来都不知道:。假设您使用的是SMTP客户端,您可以将其配置为将电子邮件“发送”到文件夹,然后您可以读取并检查它们。不过,我从未测试过实际的电子邮件。如果我使用的是框架类,那么似乎没有必要。这看起来更像是对基础设施的测试。但我想这一切都是有道理的。集成测试会是什么样子,你能给出一些基于这个的例子吗?在你的第二次测试中,真正的电子邮件将被发送,因为我没有看到moq?那么这更像是集成测试吗?我在谷歌上搜索并发现了这个,我从来都不知道:。假设您使用的是SMTP客户端,您可以将其配置为将电子邮件“发送”到文件夹,然后您可以读取并检查它们。不过,我从未测试过实际的电子邮件。如果我使用的是框架类,那么似乎没有必要。这看起来更像是对基础设施的测试。但我想一切都有理由。