我正在使用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; }
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<T>
。
[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);
}
我注意到测试通过了。由于我在其他地方没有看到这个,我明白这不是最佳做法。我问的是,为什么不使用这个,以及在Moq It.IsAny<T>()
的{{1}}或模拟对象中使用Return
会出现什么问题?
答案 0 :(得分:3)
class RobProject(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
意味着在Moq表达式中用于过滤和匹配参数。
允许在方法调用中为参数指定匹配条件,而不是特定的参数值。 &#34;它&#34;是指匹配的参数。
It
通常在方法调用的实际参数值不相关时使用。当作为It.IsAny<T>()
或Setup
表达式Verify
之外的值传递时,会传递泛型参数的默认值。因此,对于引用类型,它将传递 null 等等。
虽然在您的场景中它没有失败,但通常建议不要将It.IsAny<T>()
类用于除了传递给模拟依赖项的匹配参数之外的其他任何内容。
通常使用It
在执行测试时返回使用值。如果受测试的主体在调用模拟时期望值而非模拟Returns
返回Setup
,则测试将以意外的方式运行。
给出以下简单示例
It.IsAny<T>()
由于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;
}
}
的使用不当,以下测试将因NullReferenceException
而失败
It.IsAny<T>()