-
C#教程之C# Moq(2)
试听地址 https://www.xin3721.com/eschool/CSharpxin3721/
Dispose()); // custom matchers mock.Setup(foo => foo.DoSomething(IsLarge())).Throws<ArgumentException>(); ... public string IsLarge() { return Match.Create<string>(s => !String.IsNullOrEmpty(s) && s.Length > 100); }
Mocking internal types: Add either of the following custom attributes (typically in AssemblyInfo.cs) to the project containing the internal types — which one you need depends on whether your own project is strong-named or not:
// This assembly is the default dynamic assembly generated by Castle DynamicProxy,
// used by Moq. If your assembly is strong-named, paste the following in a single line:
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=00...cc7")]
// Or, if your own assembly is not strong-named, omit the public key:
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]
Starting in Moq 4.8, you can create your own custom default value generation strategies (besides DefaultValue.Empty and DefaultValue.Mock) by subclassing DefaultValueProvider, or, if you want some more convenience, LookupOrFallbackDefaultValueProvider:
class MyEmptyDefaultValueProvider : LookupOrFallbackDefaultValueProvider
{
public MyEmptyDefaultValueProvider()
{
base.Register(typeof(string), (type, mock) => "?");
base.Register(typeof(List<>), (type, mock) => Activator.CreateInstance(type));
}
}
var mock = new Mock<IFoo> { DefaultValueProvider = new MyEmptyDefaultValueProvider() };
var name = mock.Object.Name; // => "?"
2.10 LINQ to Mocks
Moq is the one and only mocking framework that allows specifying mock behavior via declarative specification queries. You can think of LINQ to Mocks as:
Keep that query form in mind when reading the specifications:
var services = Mock.Of<IServiceProvider>(sp =>
sp.GetService(typeof(IRepository)) == Mock.Of<IRepository>(r => r.IsAuthenticated == true) &&
sp.GetService(typeof(IAuthentication)) == Mock.Of<IAuthentication>(a => a.AuthenticationType == "OAuth"));
// Multiple setups on a single mock and its recursive mocks
ControllerContext context = Mock.Of<ControllerContext>(ctx =>
ctx.HttpContext.User.Identity.Name == "kzu" &&
ctx.HttpContext.Request.IsAuthenticated == true &&
ctx.HttpContext.Request.Url == new Uri("http://moqthis.com") &&
ctx.HttpContext.Response.ContentType == "application/xml");
// Setting up multiple chained mocks:
var context = Mock.Of<ControllerContext>(ctx =>
ctx.HttpContext.Request.Url == new Uri("http://moqthis.me") &&
ctx.HttpContext.Response.ContentType == "application/xml" &&
// Chained mock specification
ctx.HttpContext.GetSection("server") == Mock.Of<ServerSection>(config =>
config.Server.ServerUrl == new Uri("http://moqthis.com/api"));
LINQ to Mocks is great for quickly stubbing out dependencies that typically don't need further verification. If you do need to verify later some invocation on those mocks, you can easily retrieve them with Mock.Get(instance).
3 FAQ
3.1 static class/method
Moq 不支持对静态类或方法的 mock. 作为变通,可以使用实例方法来调用静态方法,再去 mock 实例方法。