C# Moq-在设置中使用它时会发生什么。iAny';她回来了吗?
我使用Moq在C#中执行单元测试。特别是在一个测试中,我在C# Moq-在设置中使用它时会发生什么。iAny';她回来了吗?,c#,unit-testing,moq,C#,Unit Testing,Moq,我使用Moq在C#中执行单元测试。特别是在一个测试中,我在System.Net.Mail.SmtpClient上创建了一个接口包装器,以便对其进行模拟 public class SmtpClient : ISmtpClient { public string Host { get; set; } public int Port { get; set; } public ICredentialsByHost Credentials { get; set; } pub
System.Net.Mail.SmtpClient
上创建了一个接口包装器,以便对其进行模拟
public class SmtpClient : ISmtpClient
{
public string Host { get; set; }
public int Port { get; set; }
public ICredentialsByHost Credentials { get; set; }
public bool EnableSsl { get; set; }
public void Send(MailMessage mail)
{
var smtpClient = new System.Net.Mail.SmtpClient
{
Host = Host,
Port = Port,
Credentials = Credentials,
EnableSsl = EnableSsl
};
smtpClient.Send(mail);
}
}
在我对这个包装器的测试中,为了确保调用方法Send()
,我模拟了接口,在设置模拟时,我使用Setup()
为该对象的属性赋值。在所有文档中,我看到这些设置的.Return()
正在返回这些方法所期望的特定类型的值。然而,在我进一步理解它之前,我在返回中使用了it.IsAny
[ClassInitialize]
public static void ClassInitialize(TestContext testContext)
{
_smtpClientMock = new Mock<ISmtpClient>(MockBehavior.Strict);
_smtpClientMock.Setup(x => x.Port).Returns(8080);
_smtpClientMock.Setup(x => x.EnableSsl).Returns(false);
_smtpClientMock.Setup(x => x.Host).Returns("host");
_smtpClientMock.Setup(x => x.Credentials).Returns(It.IsAny<NetworkCredential>());
_smtpClientMock.Setup(mockSend => mockSend.Send(It.IsAny<MailMessage>()));
}
[TestMethod]
public void WithValidMailMessageObject_WhenSendIsCalled_EmailClientCallsSmptClientToSendEmail()
{
//Arrange
//Act
_smtpClientMock.Object.Send(new MailMessage());
//Assert
_smtpClientMock.Verify(checkMethodIsCalled => checkMethodIsCalled.Send(It.IsAny<MailMessage>()), Times.Once);
}
[分类初始化]
公共静态void ClassInitialize(TestContext TestContext)
{
_smtpClientMock=新模拟(MockBehavior.Strict);
_smtpClientMock.Setup(x=>x.Port).Returns(8080);
_smtpClientMock.Setup(x=>x.EnableSsl).Returns(false);
_smtpClientMock.Setup(x=>x.Host).返回(“主机”);
_smtpClientMock.Setup(x=>x.Credentials).Returns(It.IsAny());
_smtpClientMock.Setup(mockSend=>mockSend.Send(It.IsAny());
}
[测试方法]
public void with validmailmessageobject_when ndiscaled_EmailClientCallsSmptClientToSendEmail()
{
//安排
//表演
_smtpClientMock.Object.Send(newmailmessage());
//断言
_验证(checkMethodIsCalled=>checkMethodIsCalled.Send(It.IsAny()),Times.Once);
}
我注意到考试通过了。因为我没有在其他地方看到过,我知道这不是最佳实践。我想问的是,为什么不使用它,以及使用它会出现什么问题。在Moq的
Setup()
或模拟对象的Return
中,IsAny()用于在Moq表达式中过滤和匹配参数
允许为方法调用中的参数指定匹配条件,而不是指定特定的参数值。“It”指的是匹配的参数
It.IsAny()
通常在方法调用的实际参数值不相关时使用。当作为设置
或验证
表达式之外的值传递时,IsAny()将传递泛型参数的默认值。因此,对于引用类型,它将传递null,以此类推
虽然在您的场景中,它不会失败,但通常建议不要将it
类用于传递给模拟依赖项的匹配参数以外的任何内容
执行测试时,通常使用返回
返回使用值。如果在调用模拟时被测试的主体期望一个值,而模拟是Setup
返回It.IsAny()
,那么测试将以意外的方式进行
下面给出一个简单的例子
public interface IDependency {
string SomeMethod();
}
public MyClass {
public bool MyMethod(IDependency input) {
var value = input.SomeMethod();
var result = "Output" + value.ToUpper(); //<-- value should not be null
return result != null;
}
}
它用于moq表达式中过滤参数。当作为设置或验证表达式之外的值传递时,它将传递泛型参数的默认值。因此,对于引用类型,它将传递一个事实,即调用了send方法,但这并不意味着您发送电子邮件的代码实际上正在工作。你花了太多的时间去担心一些几乎无关紧要的事情。单元测试功能,测试调用的方法没有那么重要。从技术上来说,该测试只是测试模拟框架是否按预期运行。如果每个人都能理解,根据我的问题,实际测试和正在测试的内容是不相关的。考虑到网上没有找到其他示例,我将最简单的测试放在一起,以演示“It.IsAny()”在返回中的用法。从这个测试中唯一可以得到的是,在返回中使用IsAny不会使测试失败。在这个场景中,它不会使测试失败。这是您所展示内容的唯一优点,在Returns()中有一种将参数从SomeMethod()传递到SomeOtherMethod()的方法。类似的东西:mock.Setup(=>\u0.SomeMethod(It.IsAny(),It.IsAny()).Returns(SomeOtherMethod(It.IsAny(),It.IsAny()));
[TestMethod]
public void MyMethod_Should_Return_True() {
//Arrange
var mock = new Mock<IDependency>();
mock.Setup(_ => _.SomeMethod()).Returns(It.IsAny<string>());
var subject = new MyClass();
var expected = true;
//Act
var actual = subject.MyMethod(mock.Object);
//Assert
Assert.AreEqual(expected, actual);
}