我在Dimecasts.net上看过这个Introduction to Moq video。在视频中,当这个人设置他的moq测试时,他有以下代码:
[Test]
public void TestWithMock()
{
var mockEmailService = new Mock<IEmailService>();
mockEmailService.Expect(x =>
x.SendEmail(It.IsAny<string>,It.IsAny<string>)).Returns(true);
var emailer = new Emailer(mockEmailService.Object);
emailer.SendBatchEmails();
}
以下是我的问题:
1)moq是否循环遍历测试SendBatchEmails方法的所有不同类型的字符串? 我想我对模拟的工作方式有点困惑。
2)有人可以解释Expect部分的lambda语法吗?
3)作者首先在SendEmail函数中有“”,“”,但是失败了,所以他反而放了
It.IsAny<string>
,但我仍然不清楚为什么它失败了“”,“”。
Stackoverflow没有将字符串关键字放在尖括号中。(已修复)
答案 0 :(得分:4)
1)Moq不影响SendBatchEmails
的工作方式,因为您没有嘲笑Emailer
类。相反,你是在模拟IEmailService
接口,所以如果Emailer
类调用IEmailService
对象上的方法,Moq将捕获这些调用。
2)您告诉Moq您希望调用SendEmail
上的IEmailService
方法。您还告诉Moq,在调用SendEmail
时,您希望Moq自动返回true
。
由于Moq对象被传递到Emailer
类,因此该测试将测试SendBatchEmails
中的代码是否调用SendEmail
方法。
3)只有参数匹配才能实现期望。如果您告诉Moq,您希望SendEmail
作为参数调用"", ""
,并且使用不同的字符串调用SendEmail
,则会失败。 It.IsAny<string>()
告诉Moq将期望与任何字符串作为参数进行匹配。
答案 1 :(得分:1)
它不会循环遍历任何字符串,所设置的期望将简单地匹配调用SendEmail时给出的任何字符串,返回真实结果。期望中的lambda在设置期望的对象上设置函数调用匹配,在本例中为mockEmailService。变量x在此处采用作为期望主题的对象的值。它将在该对象上匹配的方法是SendEmail,并且当使用任何字符串参数调用SendEmail时它将匹配。当预期的调用发生时,它将返回值true。
可能是它最初失败的原因是SendEmail被调用了一对与“”,“”不匹配的参数。这意味着没有达到预期,因此它没有回归。未达到期望的事实可能未通过测试,但当方法返回false时,SendBatchEmail也可能失败。
答案 2 :(得分:1)
1)你是什么意思,不同类型的字符串?只有一种类型的字符串......就是字符串。
模拟的作用是自动创建一个实现所提供的接口或抽象类的新对象类型。在这种情况下,Moq将生成一个新的类类型,其名称类似于“IEmailService_a324bc54ff123827d”。此类型将实现IEmailService接口的所有方法以返回null。
3)我会在(2)之前先回答这个问题。 “”,“”失败的原因是因为它会注册一个对mockEmailService.SendMail(“”,“”)的预期调用。如果用任何其他参数调用它,那么期望就会失败。使用IsAny()意味着你不关心参数值,你只是期望方法调用发生。
最后,(2) - 语法正在向Moq注册期望。 Expect()方法只是要求调用的方法 - 所以在这种情况下,mockEmailInstance.SendMail(),带有任何参数。