如何使用Moq并检查传递给函数的对象的一部分?

时间:2013-01-21 04:35:15

标签: c# .net unit-testing mocking moq

我正在尝试将单元测试添加到我拥有的身份验证类中。所以,基本上它的作用是我调用Login并且我希望它会返回true并且副作用会添加一个cookie。

到目前为止,这是我的单元测试:

var mock=new Mock<IServerContext>(); //AddCookie method is within IServerContext
FSCAuth.Config.Server=mock; //set authentication to use mocked interface
mock.Setup(x=>x.AddCookie(new HttpCookie().Name=="??")); //question here
FSCAuth.Login("foo", "bar", false);
mock.VerifyAll();

我的问题是如何检查传入AddCookie的参数?基本上,我想做的就是

bool AddCookieVerify(HttpCookie cookie)
{
    return cookie.Name=="foobar"
}

如果我的验证函数返回false,则抛出错误。我不明白如何在Moq中表达这个操作。

我该怎么做?

2 个答案:

答案 0 :(得分:2)

Moq包含It静态类,可让您指定所期望的参数类型。例如,而不是占位符行

mock.Setup(x => x.AddCookie(new HttpCookie().Name == "??"));

你可以做到

mock.Setup(x => x.AddCookie(It.Is<HttpCookie>(cookie => cookie.Name == "Whatever")));

然后它将无法验证,除非它传递的值满足该表达式。

此外,您可能会考虑从Setup()后跟VerifyAll()转换为仅在事后使用Verify()的内容,例如:

var mock = new Mock<IServerContext>(); // AddCookie method is within IServerContext
FSCAuth.Config.Server = mock.Object; //set authentication to use mocked interface
FSCAuth.Login("foo", "bar", false);
mock.Verify(x => x.AddCookie(It.Is<HttpCookie>(cookie => cookie.Name == "Whatever")), Times.Once());

这可以避免您提前明确设置您的期望,并将其降低到额外的一行代码。

答案 1 :(得分:0)

下面设置AddCookie以期望HttpCookie属性设置为特定值的任何Name实例。

var mock=new Mock<IServerContext>(); //AddCookie method is within IServerContext
FSCAuth.Config.Server = mock.Object; //set authentication to use mocked interface
mock.Setup(x => x.AddCookie(It.Is<HttpCookie>(h => h.Name == "foobar"))); //question here
FSCAuth.Login("foo", "bar", false);

mock.VerifyAll();

另请注意,设置FSCAuth.Config.Server时,您必须使用MockedInstance.Object