设置 Mock 以重定向到重载方法

Pal*_*lmi 2 c# unit-testing moq

我有一个方法叫做:

SendMail(string from, string to, string subject, string smtpServer)
Run Code Online (Sandbox Code Playgroud)

和重载的方法

SendMail(string from, string to, string subject, SmtpClient smtpClient)
Run Code Online (Sandbox Code Playgroud)

在我的单元测试中,我想设置我的MailService模拟,以便在SendMail(string, string, string, string)调用方法时我想调用重载的方法SendMail(string, string, string, SmtpClient)并将最后一个参数修改为创建的SmtpClient测试对象。

有没有办法做到这一点?

Mic*_*han 5

您想要的是.Callback(...)在您的安装程序中使用

mailServiceMock
  .Setup(m => m.SendMail(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())
  .CallBack((string from, string to, string subject, string server) => mailService.SendMail(from, to, subject, server, SomeSMTPServer)
Run Code Online (Sandbox Code Playgroud)

更重要的是你为什么要这样做?

通常你只会测试你的模拟是否被调用(字符串,搅拌,字符串,字符串)。

然后是另一个 TestClass/Fixture,当你调用

(string from, string to, string subject, string smtpServer) 
Run Code Online (Sandbox Code Playgroud)

重载,您实际上SmtpServer使用正确的详细信息调用重载。

编辑:评论后

mailService 不是错别字。

这将是:

  1. 相同的模拟 isntance(例如mailServiceMock.Object) if var mailServiceMock = new Mock<ParentClassNotInterface>{ CallsBase = true }。这当然意味着您的方法必须是虚拟的。
  2. 类/接口的实际具体实现。

至于第二个注释,如果我是你,我会将其分解为以下一个/一些/所有:

  • 单元测试调用类/方法调用SendServer(string, string, string, string). 我将使用我在博客中描述的技术:CodePerf[dot]NET - TDD – Mock.Throw 接口调用验证技术

  • 单元测试,当你调用SendServer(string, string, string, string)它时SendServer(string, string, string, SmtpServer),SmtpServer 被正确设置。

  • SendServer(string, string, string, SmtpServer)` 实际发送电子邮件的集成测试。

  • 可能是一个端到端的测试(没有模拟),这一切都有效。