Moq - What happens when using It.IsAny in a setup's return?
我正在使用 Moq 在 C# 中执行单元测试。特别是一项测试,我在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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); } } |
在我对这个package器的测试中,为了确保调用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | [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 的
Allows the specification of a matching condition for an argument in a method invocation, rather than a specific argument value."It" refers to the argument being matched.
虽然在您的场景中它不会失败,但通常建议不要将
通常在执行测试时使用
给出以下简单示例
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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; } } |
由于
使用不当,以下测试将失败并返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [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); } |