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的常用使用方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!