moq 的常用使用方法(推荐)
Moq,就是Mockyou。读音可以读成Mock~you。是Mock框架的一种。用于测试中的Mock测试。Mock是模拟的意思。Mock是模拟对象的一种技术。
测试方法
//准备MockIFoo接口
varmock=newMock<IFoo>();
//配置准备模拟的方法,当调用接口中的DoSomething方法,并传递参数"bing"的时候,返回true
mock.Setup(foo=>foo.DoSomething("ping")).Returns(true);
//方法的参数中使用了out参数
//outarguments
varoutString="ack";
//当调用TryParse方法的时候,out参数返回"ack",方法返回true,lazyevaluated
mock.Setup(foo=>foo.TryParse("ping",outoutString)).Returns(true);
//ref参数
varinstance=newBar();
//仅仅在使用ref调用的时候,才会匹配下面的测试
mock.Setup(foo=>foo.Submit(refinstance)).Returns(true);
//当方法返回值得时候,还可以访问返回的值
//这里可以使用多个参数
mock.Setup(x=>x.DoSomething(It.IsAny<string>()))
.Returns((strings)=>s.ToLower());
//在被调用的时候抛出异常
mock.Setup(foo=>foo.DoSomething("reset")).Throws<InvalidOperationException>();
mock.Setup(foo=>foo.DoSomething("")).Throws(newArgumentException("command");
//延迟计算返回的结果
mock.Setup(foo=>foo.GetCount()).Returns(()=>count);
//在每一次调用的时候,返回不同的值
varmock=newMock<IFoo>();
varcalls=0;
mock.Setup(foo=>foo.GetCountThing())
.Returns(()=>calls)
.Callback(()=>calls++);
//第一次调用返回0,下一次是1,依次类推
Console.WriteLine(mock.Object.GetCountThing());
匹配参数
//任意值
mock.Setup(foo=>foo.DoSomething(It.IsAny<string>())).Returns(true);
//提供的值必须匹配一个函数,lazyevaluated
mock.Setup(foo=>foo.Add(It.Is<int>(i=>i%2==0))).Returns(true);
//匹配一个范围
mock.Setup(foo=>foo.Add(It.IsInRange<int>(0,10,Range.Inclusive))).Returns(true);
//匹配正则表达式
mock.Setup(x=>x.DoSomething(It.IsRegex("[a-d]+",RegexOptions.IgnoreCase))).Returns("foo");
属性
//普通属性
mock.Setup(foo=>foo.Name).Returns("bar");
//多层的属性
mock.Setup(foo=>foo.Bar.Baz.Name).Returns("baz");
//期望设置属性的值为"foo"
mock.SetupSet(foo=>foo.Name="foo");
//或者直接验证赋值
mock.VerifySet(foo=>foo.Name="foo");
设置属性,以便自动跟踪它的值
//开始"tracking"属性的sets/gets
mock.SetupProperty(f=>f.Name);
//提供一个默认的值
mock.SetupProperty(f=>f.Name,"foo");
//现在,你可以:
IFoofoo=mock.Object;
//保存的值
Assert.Equal("foo",foo.Name);
//重新设置一个值
foo.Name="bar";
Assert.Equal("bar",foo.Name);
还可以准备所有的属性
mock.SetupAllProperties();
事件
//抛出一个事件
mock.Raise(m=>m.FooEvent+=null,newFooEventArgs(fooValue));
//多层的后代中的事件
mock.Raise(m=>m.Child.First.FooEvent+=null,newFooEventArgs(fooValue));
//当Submit方法被调用的时候,抛出一个事件
mock.Setup(foo=>foo.Submit()).Raises(f=>f.Sent+=null,EventArgs.Empty);
//抛出异常将会触发对象底层的行为
//你可能需要在后面进行断言处理
//抛出一个自定义的事件
publicdelegatevoidMyEventHandler(inti,boolb);
publicinterfaceIFoo{eventMyEventHandlerMyEvent;}
varmock=newMock<IFoo>();
...
//传递自定义的事件参数
mock.Raise(foo=>foo.MyEvent+=null,25,true);
回调
varmock=newMock<IFoo>();
mock.Setup(foo=>foo.Execute("ping"))
.Returns(true)
.Callback(()=>calls++);
//使用调用的参数
mock.Setup(foo=>foo.Execute(It.IsAny<string>()))
.Returns(true)
.Callback((strings)=>calls.Add(s));
//使用泛型语法
mock.Setup(foo=>foo.Execute(It.IsAny<string>()))
.Returns(true)
.Callback<string>(s=>calls.Add(s));
//使用多个参数
mock.Setup(foo=>foo.Execute(It.IsAny<int>(),It.IsAny<string>()))
.Returns(true)
.Callback<int,string>((i,s)=>calls.Add(s));
//调用之前和之后的回调
mock.Setup(foo=>foo.Execute("ping"))
.Callback(()=>Console.WriteLine("Beforereturns"))
.Returns(true)
.Callback(()=>Console.WriteLine("Afterreturns"));
验证
mock.Verify(foo=>foo.Execute("ping"));
//在验证失败的时候,提供自定义的错误提示信息
mock.Verify(foo=>foo.Execute("ping"),"WhendoingoperationX,theserviceshouldbepingedalways");
//从没有被调用的方法
mock.Verify(foo=>foo.Execute("ping"),Times.Never());
//至少调用过一次
mock.Verify(foo=>foo.Execute("ping"),Times.AtLeastOnce());
mock.VerifyGet(foo=>foo.Name);
//验证对属性的赋值.
mock.VerifySet(foo=>foo.Name);
//验证对于属性设置特定的值
mock.VerifySet(foo=>foo.Name="foo");
//验证匹配的参数
mock.VerifySet(foo=>foo.Value=It.IsInRange(1,5,Range.Inclusive));
自定义Mock行为
Mock的行为分为严格的Strict和宽松的Loose,默认为宽松的。在严格模式下,使用任何没有被指定的行为,都将会抛出异常,宽松模式下,不会抛出任何异常,方法将会返回默认值或者空的数组等等。
varmock=newMock<IFoo>(MockBehavior.Strict);
如果没有重写基类的实现,默认将不会调用基类,在MockWeb/Html控件的是必须的。
varmock=newMock<IFoo>{CallBase=true};
创造自动递归的Mock,Mock对象对于它的任何成员将会返回一个新的Mock对象。
varmock=newMock<IFoo>{DefaultValue=DefaultValue.Mock};
//默认是DefaultValue.Empty
//现在这个属性将会返回一个新的Mock对象
IBarvalue=mock.Object.Bar;
//可以使用返回的Mock对象,后即对属性的访问返回相同的对象实例
//这就允许我们可以进行后继的设置
//setfurtherexpectationsonitifwewant
varbarMock=Mock.Get(value);
barMock.Setup(b=>b.Submit()).Returns(true);
中心化的Mock实例创建和管理:你可以在一个地方使用MockRepository创建和验证所有的Mock对象,设置MockBehavior,CallBse和DefaultValue约束。
varfactory=newMockFactory(MockBehavior.Strict){DefaultValue=DefaultValue.Mock};
//创建Mock对象
varfooMock=factory.Create<IFoo>();
//在创建的时候重写仓库的设置
varbarMock=factory.Create<IBar>(MockBehavior.Loose);
//验证通过仓库创建的对象
factory.Verify();
其它
//用在测试用例的开始
usingMoq.Protected()
//测试中
varmock=newMock<CommandBase>();mock.Protected()
.Setup<int>("Execute")
.Returns(5);
//如果用到了参数匹配,必须使用ItExpr来代替It
//以后计划改进
mock.Protected()
.Setup<string>("Execute",ItExpr.IsAny<string>())
.Returns(true);
高级特性
//从Mock实例重新获得Mock对象
IFoofoo=//getmockinstancesomehow
varfooMock=Mock.Get(foo);
fooMock.Setup(f=>f.Submit()).Returns(true);
//实现多个接口
varfoo=newMock<IFoo>();
vardisposableFoo=foo.As<IDisposable>();
//现在IFoomock已经实现了接口IDisposable:)disposableFoo.Setup(df=>df.Dispose());
//定制匹配
mock.Setup(foo=>foo.Submit(IsLarge())).Throws<ArgumentException>();...
publicstringIsLarge()
{
returnMatch<string>.Create(s=>!String.IsNullOrEmpty(s)&&s.Length>100);
}
以上所述是小编给大家介绍的moq的常用使用方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!