使用Moq让单元测试变得更简单
作者:网络转载 发布时间:[ 2013/11/18 16:49:27 ] 推荐标签:
这个类用于模拟对象的行为。像是否按照默认的模式去模拟。让我们进一步看看他的定义:
|
namespace Moq
{
// Summary:
// Options to customize the behavior of the mock.
public enum MockBehavior
{
// Summary:
// Causes the mock to always throw an exception for invocations that don't have
// a corresponding setup.
Strict = 0,
//
// Summary:
// Will never throw exceptions, returning default values when necessary (null
// for reference types, zero for value types or empty enumerables and arrays).
Loose = 1,
//
// Summary:
// Default mock behavior, which equals Moq.MockBehavior.Loose.
Default = 1,
}
}
|
现在,看看如下例子:
var mock = new Mock<IFake>(MockBehavior.Strict);
指定了mock行为是的,如果没有按照预期的Setup会抛出异常。
MockFactory
这是一个模拟对象的工厂,我们不仅仅可以定制创建模拟对象的配置,也可以成批测试它们。看看下边例子:
|
var factory = new MockFactory(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock };
// Create a mock using the factory settings
var fooMock = factory.Create<IFake>();
// Create a mock overriding the factory settings
var barMock = factory.Create<IEmailSender>(MockBehavior.Loose);
// Verify all verifiable expectations on all mocks created through the factory
factory.Verify();
|
在前边,我们已经介绍了传统方式的创建模拟对象,它不会去真正的调用方法,而是仅仅去执行一些假设:如果...那么返回... 。
在下边的例子里,我将继续介绍一些Mock<T> 类中基本并且重要的方法。
Verification
有时候,我们要确定一个方法是否被调用了,或者甚至要知道它被调用了多少次。一个比较传统的方式是使用Verify()方法。看看下边例子:
mock.Verify(foo => foo.DoSomething("Ping"), Times.Once());
上边的代码尝试验证DoSomething("Ping")需要被调用,并且只调用一次。出了Once选项,这里也有更多的选项可供你选择去决定这个方法需要被调用多少次。如: AtLeast, AtLeastOnce, AtMost, AtMostOnce, Between, Equals, Exactly, Never, 和Once
一旦我们已经模拟了对象,验证将是个轻松的任务,看看下边的例子:
|
public void Test_FindByName_GetCalled()
{
// create some mock data
IList<Product> products = new List<Product>
{
new Product { ProductId = 1, Name = "C# Unleashed",
Description = "Short description here", Price = 49.99 },
new Product { ProductId = 2, Name = "ASP.Net Unleashed",
Description = "Short description here", Price = 59.99 },
new Product { ProductId = 3, Name = "Silverlight Unleashed",
Description = "Short description here", Price = 29.99 }
};
Mock<IProductRepository> mock = new Mock<IProductRepository>();
//mock
//.Setup(sender => sender.FindById(It.IsAny<int>()))
//.Returns((int s) => products.Where(
// x => x.ProductId == s).Single());
mock.Object.FindById(1);
mock
.Verify(x => x.FindById(1), Times.Once());
}
}
|
在上边的例子里,有两个地方值得注意。
首先是mock.Object.FindById(1)。为了在这个case里让一切变得简单,我们直接调用mock.Object的方法。为什么呢?因为我们这个case只关注这个方法被调用的次数,而不关注返回值。当然,在实际的应用中我们很少这样做。
第二,你有没有注意到被注释掉的句子。它仅仅是一个“如果,那么”句子。意思是说,如果Setup 好了,返回我们定义的值。
由于调查的时间有限,还有很多关于Mock给力的地方我没有涉及到。我们可以去查看官方的资料。欢迎共同讨论。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。

sales@spasvo.com