我在一些集成测试中使用 Moq(更新不属于我自己的现有测试脚本和代码),并且我正在测试一个 BuinessService,其中注入了一个发送电子邮件的电子邮件接口。
public interface IEmailService
{
void CreateMailItem(string To, string Subject, string Body);
string GetEmailAddress(string staffmember);
}
Run Code Online (Sandbox Code Playgroud)
最初我只是 Moq'd IEmailService接口并且工作正常,但由于代码的实现方式,我需要调用默认接口实现(即EmailService)进行测试。我知道我不应该。
我知道我可以起订量如下所示的方法,但我想做的是让代码调用原始实现EmailService.CreateMailItem 并仅更改单个参数,以便将电子邮件发送到测试帐户而不是真实帐户。
var emailMock = new Mock<EmailService>() { CallBase = true };
emailMock.Setup(x => x.CreateMailItem("test@test.com", It.IsAny<string>(), It.IsAny<string>()));
email = emailMock.Object;
Run Code Online (Sandbox Code Playgroud)
我可以使用 Moq 调用原始 CreateMailItem 方法,但将“To”参数更改为我的测试电子邮件帐户并保留其他参数不变。
无论你想做什么——你都做错了。
如果EmailService这是您要测试的系统,那么您永远不应该嘲笑它。Assert只需使用适当的参数和结果调用您想要测试的方法即可。
如果EmailService是一个依赖项,那么您永远不应该调用实际的实现 - 这会错过模拟某些内容的全部要点,您希望将自己与实现断开并提供一个模拟方法,该方法将简单地执行系统所期望的操作测试。
编辑:
您可以使用 Moq 并以这种方式进行破解:
var emailInstance = new EmailService():
var emailMock = new Mock<EmailService>() { CallBase = true };
emailMock.Setup(x => x.CreateMailItem(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
.Callback((_, arg2, arg3) => emailInstance.CreateMailItem("test@test.com", arg2, arg3));
Run Code Online (Sandbox Code Playgroud)
因此,现在当您使用任何参数调用时emailMock.CreateMailItem,它会将调用重定向到实际实例,并与您的测试电子邮件交换第一个参数。
请注意,此类测试称为集成测试。您实际上是在实时(尽管是预制的)环境中测试模块如何相互交互。如果您可以强制被测系统使用测试电子邮件而不是使用模拟,可能会更好,但这应该可以完成工作。
| 归档时间: |
|
| 查看次数: |
5243 次 |
| 最近记录: |