使用接口属性setter时,Moq VerifySet失败

时间:2011-11-28 09:49:24

标签: mocking nunit moq

我的Nunit测试中有以下代码:

    [Test]
    public void SmtpSend_UsingSystemCredentials_SetsSmtpClientCredentials()
    {
        const string smtppwd = "smtppwd";
        const string smtpuser = "smtpuser";
        const string smtphost = "smtphost";
        const int smtpport = 333;

        _emailManager.Setup(x => x.ValidateSmtpSettings()).Returns(true);
        _emailTransportConfig.SetupGet(x => x.SmtpPassword).Returns(smtppwd);
        _emailTransportConfig.SetupGet(x => x.SmtpUsername).Returns(smtpuser);
        _emailTransportConfig.SetupGet(x => x.SmtpHost).Returns(smtphost);
        _emailTransportConfig.SetupGet(x => x.SmtpPort).Returns(smtpport);            
        _smtpClient.SetupAllProperties();

        _smtpHandler.Send(null, "from@test.com", "to@test.com", "subject", "body", true);
        _smtpClient.VerifySet(x => x.Port = smtpport);
        _smtpClient.VerifySet(x => x.Host = smtphost);

        // Todo Why is this not working?
        _smtpClient.VerifySet(x => x.Credentials = new NetworkCredential(smtpuser, smtppwd));
    }

我可以看到代码落入此函数:

private void SetSystemSmtpAccountSettings()
    {           
        _smtpClient.Credentials = new NetworkCredential
        {
            UserName = _emailTransportConfig.SmtpUsername,
            Password = _emailTransportConfig.SmtpPassword
        };
        _smtpClient.Host = _emailTransportConfig.SmtpHost;
        _smtpClient.Port = _emailTransportConfig.SmtpPort;
    }

但我无法理解的是VerifySet调用失败的原因。

3 个答案:

答案 0 :(得分:2)

您的代码示例可以使用一些说明,但我相信您的问题在于尝试针对new NetworkCredential实例进行验证,该实例不是在测试方法中设置的实际实例,因此验证失败。您似乎正在尝试验证是否在Credentials属性上正确设置了用户名和密码。这是一个基于状态的测试,更容易通过几个断言进行验证:

Assert.IsNotNull(_smtpClient.Credentials);
Assert.AreEqual(_smtpClient.Credentials.UserName, smtpuser);
Assert.AreEqual(_smtpClient.Credentials.Password, smtppwd);

答案 1 :(得分:1)

正如@Daz Lewis所说,你的VerifySet正在检查另一个实例。相反,请尝试将It.Is与匹配表达式一起使用:

_smtpClient.VerifySet(x => x.Credentials = It.Is<NetworkCredential>(c => c.UserName == smtpuser && c.Password == smtppwd));

答案 2 :(得分:0)

我有类似的情况,但是使用工厂,所以拥有凭证的类是模拟。

mockCreate = new Mock<IWebRequestCreate>();
mockRequest = new Mock<WebRequest>();
mockCreate.Setup(x => x.Create(It.IsAny<Uri>()))
                .Returns(mockRequest.Object);
webrequest = new HTTPRequestFactory(mockCreate.Object);
mockRequest.SetupProperty(mr => mr.Credentials);
mockRequest.SetupProperty(mr => mr.Credentials.UserName);
mockRequest.SetupProperty(mr => mr.Credentials.Password);

//setup username and password and send to factory
WebResponse response = webrequest.GetWebResponse(testURI);
mockCreate.VerifyAll();
mockRequest.VerifySet(mr => mr.Credentials = It.Is<NetworkCredential>(c => c.UserName == "user" && c.Password == "password"));
Assert.AreEqual("user", mockRequest.Object.Credentials.UserName);
Assert.AreEqual("user", mockRequest.Object.Credentials.Password);

adrifts答案工作,Daz不会编译。有关何处了解更多原因的任何提示? IntelliSense表示,因为ICredentials没有UserNamePassword的定义。