理解Moq有困难
本文关键字:Moq 理解 | 更新日期: 2023-09-27 18:29:29
我很难掌握Moq框架。在Moq网站上,他们给出了这个例子。。。
// Assumptions:
public interface IFoo {
public bool DoSomething(string);
public bool TryParse(string, out string));
}
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
Moq的设置在这里做什么?
// out arguments
var outString = "ack";
// TryParse will return true, and the out argument will return "ack", lazy evaluated
mock.Setup(foo => foo.TryParse("ping", out outString)).Returns(true);
这里也有同样的问题。。正在设置什么?
有人知道Moq的指南吗?它可能会更深入?我读过这篇SO文章,其中推荐了《.NET中的单元测试与示例的艺术》一书,但这本书很旧,已经绝版了。
对于mocking的一般背景,这个答案很好地解释了它以及为什么您可能想在单元测试中使用它。
具体来说,Moq是一个库,它允许您轻松地创建mock对象并控制它们的行为。它最容易用例子来描述,所以让我们看看你的第一个代码示例:
public interface IFoo {
public bool DoSomething(string);
public bool TryParse(string, out string));
}
/* 1 */ var mock = new Mock<IFoo>();
/* 2 */ mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
第1行创建IFoo
接口的模拟实现。在幕后,Moq正在使用Castle DynamicProxy库动态创建IFoo
的具体实现,然后将其封装在自己的Mock
类中,以便我们可以配置其行为。
因此,现在我们有了一个mock对象,我们将经常需要配置它对调用其方法的响应方式。这样,我们就可以测试被测系统对它的反应。第2行的Setup
方法正是这样做的,它告诉我们的mock对象在用等于"ping"
的参数调用DoSomething
时返回true
。想象一下,你正在使用这个mock来测试下面这样的类:
public class TestObject
{
public string TestMethod(IFoo foo)
{
if (foo.DoSomething("ping"))
return "ping";
else if (foo.DoSomething("pong"))
return "pong";
return "blah";
}
}
为了获得完整的测试覆盖率,您需要IFoo
的实现,它可以:
- 在一次测试中为
"ping"
返回true
- 在另一个测试中为
"pong"
返回true
- 为上次测试中的任何参数返回
false
您可以创建具有此行为的模拟对象,例如:
public class MockFoo : IFoo
{
string trueValue;
public MockFoo(string trueValue)
{
this.trueValue = trueValue;
}
public bool DoSomething(string value)
{
return value == trueValue;
}
}
但当你有复杂的逻辑、多个参数或许多依赖关系时,这是一种痛苦;它只是规模不大。这就是mock对象和Moq可以让事情变得容易的地方。Moq中三个测试的相同设置是:
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
mock.Setup(foo => foo.DoSomething("pong")).Returns(true);
mock.Setup(foo => foo.DoSomething(It.IsAny<string>())).Returns(false);
在我看来,这更简单、更能表达您对IFoo
依赖项的期望。
至于一个指南,我认为你最好有一个关于嘲笑的指南,而不是一个专门针对Moq的指南。Moq只是一个让使用mock对象变得更容易的库,Quickstart是使用Moq机制的一个很好的参考。这里有几十个嘲讽的教程和指南,只是找一些。记住,直到我开始使用它们,它才真正"点击"我。找到一个编码卡塔,试着自己嘲笑!