• moq 的常用使用方法


    测试方法

    复制代码
     1 // 准备 Mock IFoo 接口
     2 var mock = new Mock<IFoo>(); 
     3 // 配置准备模拟的方法,当调用接口中的 DoSomething 方法,并传递参数 "bing" 的时候,返回 true
     4 mock.Setup(foo => foo.DoSomething("ping")).Returns(true);   
     5 
     6 // 方法的参数中使用了 out 参数
     7 // out arguments 
     8 var outString = "ack"
     9 // 当调用 TryParse 方法的时候,out 参数返回 "ack", 方法返回 true, lazy evaluated 
    10 mock.Setup(foo => foo.TryParse("ping"out outString)).Returns(true);   
    11 
    12 // ref 参数
    13 var instance = new Bar(); 
    14 // 仅仅在使用 ref 调用的时候,才会匹配下面的测试
    15 mock.Setup(foo => foo.Submit(ref instance)).Returns(true);  
    16  
    17 // 当方法返回值得时候,还可以访问返回的值
    18 // 这里可以使用多个参数
    19 mock.Setup(x => x.DoSomething(It.IsAny<string>()))
    20                  .Returns((string s) => s.ToLower()); 
    21 
    22 // 在被调用的时候抛出异常
    23 mock.Setup(foo => foo.DoSomething("reset")).Throws<InvalidOperationException>(); 
    24 mock.Setup(foo => foo.DoSomething("")).Throws(new ArgumentException("command");   
    25 
    26 // 延迟计算返回的结果 
    27 mock.Setup(foo => foo.GetCount()).Returns(() => count);   
    28 
    29 // 在每一次调用的时候,返回不同的值 
    30 var mock = new Mock<IFoo>(); 
    31 var calls = 0
    32 mock.Setup(foo => foo.GetCountThing())
    33      .Returns(() => calls)
    34      .Callback(() => calls++); 
    35 
    36 // 第一次调用返回 0, 下一次是 1, 依次类推
    37 Console.WriteLine(mock.Object.GetCountThing());
    复制代码

    匹配参数

    复制代码
     1 // 任意值 
     2 mock.Setup(foo => foo.DoSomething(It.IsAny<string>())).Returns(true);   
     3 
     4 // 提供的值必须匹配一个函数, lazy evaluated 
     5 mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true);    
     6 
     7 // 匹配一个范围 
     8 mock.Setup(foo => foo.Add(It.IsInRange<int>(010, Range.Inclusive))).Returns(true);    
     9 
    10 // 匹配正则表达式
    11 mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");
    复制代码

    属性

    复制代码
     1 // 普通属性
     2 mock.Setup(foo => foo.Name).Returns("bar");   
     3 
     4 // 多层的属性
     5 mock.Setup(foo => foo.Bar.Baz.Name).Returns("baz");  
     6 
     7 // 期望设置属性的值为 "foo" 
     8 mock.SetupSet(foo => foo.Name = "foo");  
     9 
    10 // 或者直接验证赋值 
    11 mock.VerifySet(foo => foo.Name = "foo");
    复制代码

    设置属性,以便自动跟踪它的值

    复制代码
     1 // 开始 "tracking" 属性的 sets/gets 
     2 mock.SetupProperty(f => f.Name);  
     3 
     4 // 提供一个默认的值
     5 mock.SetupProperty(f => f.Name, "foo");   
     6 
     7 // 现在,你可以:  
     8 IFoo foo = mock.Object; 
     9 
    10 // 保存的值 
    11 Assert.Equal("foo", foo.Name);  
    12 
    13 // 重新设置一个值
    14 foo.Name = "bar"
    15 Assert.Equal("bar", foo.Name);
    复制代码

    还可以准备所有的属性

    mock.SetupAllProperties();

    事件

    复制代码
     1 // 抛出一个事件 
     2 mock.Raise(m => m.FooEvent += nullnew FooEventArgs(fooValue));  
     3 
     4 // 多层的后代中的事件 
     5 mock.Raise(m => m.Child.First.FooEvent += nullnew FooEventArgs(fooValue));  
     6 
     7 // 当 Submit 方法被调用的时候,抛出一个事件 
     8 mock.Setup(foo => foo.Submit()).Raises(f => f.Sent += null, EventArgs.Empty); 
     9 
    10 // 抛出异常将会触发对象底层的行为
    11 // 你可能需要在后面进行断言处理
    12 
    13 // 抛出一个自定义的事件
    14 public delegate void MyEventHandler(int i, bool b); 
    15 public interface IFoo {   event MyEventHandler MyEvent;  }  
    16 var mock = new Mock<IFoo>(); 
    17 ... 
    18 
    19 // 传递自定义的事件参数
    20 mock.Raise(foo => foo.MyEvent += null25true);
    复制代码

     回调

    复制代码
     1 var mock = new Mock<IFoo>(); 
     2 mock.Setup(foo => foo.Execute("ping"))
     3      .Returns(true)
     4      .Callback(() => calls++);   
     5 
     6 // 使用调用的参数 
     7 mock.Setup(foo => foo.Execute(It.IsAny<string>()))
     8      .Returns(true)
     9      .Callback((string s) => calls.Add(s));  
    10 
    11 // 使用泛型语法 
    12 mock.Setup(foo => foo.Execute(It.IsAny<string>()))
    13      .Returns(true)
    14      .Callback<string>(s => calls.Add(s));  
    15 
    16 // 使用多个参数
    17 mock.Setup(foo => foo.Execute(It.IsAny<int>(), It.IsAny<string>()))
    18      .Returns(true)
    19      .Callback<intstring>((i, s) => calls.Add(s));  
    20 
    21 // 调用之前和之后的回调 
    22 mock.Setup(foo => foo.Execute("ping"))
    23      .Callback(() => Console.WriteLine("Before returns"))
    24      .Returns(true)
    25      .Callback(() => Console.WriteLine("After returns"));
    复制代码

    验证

    复制代码
     1 mock.Verify(foo => foo.Execute("ping"));  
     2 
     3 // 在验证失败的时候,提供自定义的错误提示信息 
     4 mock.Verify(foo => foo.Execute("ping"), "When doing operation X, the service should be pinged always");  
     5 
     6 // 从没有被调用的方法 
     7 mock.Verify(foo => foo.Execute("ping"), Times.Never());  
     8 
     9 // 至少调用过一次 
    10 mock.Verify(foo => foo.Execute("ping"), Times.AtLeastOnce());  
    11 mock.VerifyGet(foo => foo.Name);  
    12 
    13 // 验证对属性的赋值. 
    14 mock.VerifySet(foo => foo.Name);  
    15 
    16 // 验证对于属性设置特定的值 
    17 mock.VerifySet(foo => foo.Name ="foo");  
    18 
    19 // 验证匹配的参数 
    20 mock.VerifySet(foo => foo.Value = It.IsInRange(15, Range.Inclusive));
    复制代码

     自定义 Mock 行为

    Mock 的行为分为严格的 Strict 和宽松的 Loose, 默认为宽松的。在严格模式下,使用任何没有被指定的行为,都将会抛出异常,宽松模式下,不会抛出任何异常,方法将会返回默认值或者空的数组等等。

    var mock = new Mock<IFoo>(MockBehavior.Strict);

    如果没有重写基类的实现,默认将不会调用基类,在 Mock Web/Html 控件的是必须的。

    var mock = new Mock<IFoo> { CallBase = true };

     创造自动递归的 Mock, Mock 对象对于它的任何成员将会返回一个新的 Mock 对象。

    复制代码
    var mock = new Mock<IFoo> { DefaultValue = DefaultValue.Mock }; 

    // 默认是 DefaultValue.Empty  
    // 现在这个属性将会返回一个新的 Mock 对象 
    IBar value = mock.Object.Bar;  

    // 可以使用返回的 Mock 对象, 后即对属性的访问返回相同的对象实例
    // 这就允许我们可以进行后继的设置  
    // set further expectations on it if we want 
    var barMock = Mock.Get(value); 
    barMock.Setup(b 
    => b.Submit()).Returns(true);
    复制代码

    中心化的 Mock 实例创建和管理:你可以在一个地方使用 MockRepository 创建和验证所有的 Mock 对象,设置 MockBehavior, CallBse 和 DefaultValue 约束。

    复制代码
    var factory = new MockFactory(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock };  

    // 创建 Mock 对象
    var fooMock = factory.Create<IFoo>();  

    // 在创建的时候重写仓库的设置 
    var barMock = factory.Create<IBar>(MockBehavior.Loose);  

    // 验证通过仓库创建的对象 
    factory.Verify();
    复制代码

    其它

    复制代码
    // 用在测试用例的开始 
    using Moq.Protected()  

    // 测试中
    var mock = new Mock<CommandBase>(); mock.Protected()
          .Setup
    <int>("Execute")
          .Returns(
    5);  

    // 如果用到了参数匹配, 必须使用 ItExpr 来代替 It 
    // 以后计划改进
    mock.Protected()
         .Setup
    <string>("Execute",         ItExpr.IsAny<string>())
         .Returns(
    true);
    复制代码

    高级特性

    复制代码
     1 // 从 Mock 实例重新获得 Mock 对象
     2 IFoo foo = // get mock instance somehow 
     3 var fooMock = Mock.Get(foo); 
     4 fooMock.Setup(f => f.Submit()).Returns(true);   
     5 
     6 // 实现多个接口 
     7 var foo = new Mock<IFoo>(); 
     8 var disposableFoo = foo.As<IDisposable>(); 
     9 
    10 // 现在 IFoo mock 已经实现了接口 IDisposable :) disposableFoo.Setup(df => df.Dispose());   
    11 
    12 // 定制匹配 
    13 mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); ... 
    14 public string IsLarge()  
    15 {
    16     return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100); 
    17 }
    复制代码
  • 相关阅读:
    win10 uwp 弹起键盘不隐藏界面元素
    win10 uwp 存放网络图片到本地
    win10 uwp 存放网络图片到本地
    sublime Text 正则替换
    sublime Text 正则替换
    win10 uwp 绘图 Line 控件使用
    win10 uwp 绘图 Line 控件使用
    AJAX 是什么?
    什么是 PHP SimpleXML?
    PHP XML DOM:DOM 是什么?
  • 原文地址:https://www.cnblogs.com/zcm123/p/3556242.html
Copyright © 2020-2023  润新知