zoukankan      html  css  js  c++  java
  • 初学 Moq

     

    1.什么是Moq?

     Moq是一个针对.Net开发的模拟库,它从开始就充分利用了(Linq表达式)和(Lambda表达式)。它的目标是让模拟以一种自然的方式与现有单元测试进行集成,使它更加简单、直观。使它成为了一个高生产力、类型安全、重构友好的模拟库。

    2.从哪得到Moq?

    可以直接使用VS中的插件Nuget来获取Moq并且引用到指定的项目。

     

    3.Moq原理:

    Moq使用Castle DynamicProxy完成这个任务。基本原理就是它利用反射机制的Emit功能动态生成一个空类型(也就是所有接口的方法都实例化,但是没有任何功能,只是一个程序骨架)。所以Mock的能力就在于可以利用DynamicProxy的机制快速生产出一个假对象来,用于模仿真对象的行为。

    4.Moq中的重要成员

    (1).Mock:通过这个类,我们可以得到一个Mock<T>对象。T可以是接口,也可以是类。它有一个PublicVirtual属性。比如:

    定义一个接口界面:

    public interface ITest
            {

                bool DoSomething(string actionname);

            }

    定义测试方法:

     [TestMethod]
            public void Test_Interface_ITest()
            {
                //创建Mock对象,伪造一个ITest的实现
                var mo = new Mock<ITest>();
                //设置模拟对象
                mo.Setup(foo => foo.DoSomething("Ping")).Returns(true);(注意:Setup方法的参数是一个lambda表达式:可以这样理解:当被模拟的对象foo调用它自己的方法Dosomething(),并且参数是Pring。添加后缀名Return(true)可以这样理解:前边的请求返回结果为真。这是指定的返回值。当一个请求调用DoSomething()方法时。如果传入的参数是Pring,那么就返回true。然后添加一个断言,去判断是否能得到预期结果)

                //断言它
                Assert.AreEqual(true, mo.Object.DoSomething("Ping"));

          }

    (2).It:这是一个静态类,定义了静态的泛型方法:

    Is<TValue>IsAny<TValue>IslnRange<TValue>IsRegex。去过滤参数。

    (3)MockBehavior:这个类用于模拟对象的行为。就像是否按照默认的模式去模拟

    (4)Verification:有时候,我们要确定一个方法是否被调用了,或者甚至要知道它被调用了多少次。就使用Verify()方法。;例如:

    mock.Verify(foo=>foo.DoSomething(Pring),Times.Once())

    上边的代码尝试验证DoSomething(Pring)需要被调用,并且只调用一次。出了Once选项,也有更多的选项可以选择:如:Atleast(至少)AtLeastonce(至少一次),AtMost(最多),AtMostOnce(最多一次),Between(之间),Equals(等于),Exactly(确切的),Never(从未)Once(一次)

    5.功能点介绍

    (1).带有引用或输出参数的方法。例如:

    {方法:string GetAddress(string strUser, out string Address);

    string GetFamilyCall(ref string strUser);}定义两个方法
    var customer = new Mock<ITest>();创建Mock对象,伪造一个ITest的实现

    var outString="oo";

    customer.Setup(p => p.GetAddress("", out outString)).Returns("sichuan");

    customer.Setup(p => p.GetFamilyCall(ref outString)).Returns("xx");

    (2)调用方法时抛出异常

    方法:void ShowException(string str);

    测试:var customer = new Mock<ITest>();

    customer.Setup(p => p.ShowException(string.Empty))

    .Throws(new Exception("参数不能为空!"));

    customer.Object.ShowException("");

    (3)Is<T>:匹配确定的给定类型

    customer.Setup(x => x.SelfMatch(It.Is<int>(i => i % 2 == 0))).Returns("1");

    方法SelfMatch接收int型的参数,当参数为偶数时,才返回字符串1.

    (4)IsAny<T>:匹配给定的任何值

    customer.Setup(p => p.SelfMatch(It.IsAny<int>())).Returns((int k) => "任何数:" + k);

    方法SelfMatch接收int型,且任何int型参数都可以,然后返回:任何数:”+K.

    (5)IsInRange<T>:匹配给定类型的范围

    customer.Setup(p => p.SelfMatch(It.IsInRange<int>(0, 10, Range.Inclusive))).Returns("10以内的数");

    方法SelfMatch接受int型,且当范围在[0,10]时,才返回10以内的数

    其中,这个方法,带有一个包含与排除开关。

    (6)IsRegex<T>:正则匹配

    customer.Setup(p => p.ShowException(It.IsRegex(@"^d+$")))

    .Throws(new Exception("不能是数字"));

    (7)Callbacks回调函数

    当执行某方法时,调用其内部输入的(Action)委托,有它的5种重载:

    Callback(Action)

    Callback<T>(Action<T>)

    Callback<T1, T2>(Action<T1, T2>)

    Callback<T1, T2, T3>(Action<T1, T2, T3>)

    Callback<T1, T2, T3, T4>(Action<T1, T2, T3, T4>)

    这个方法调用其内部输入的Action委托,Aciton<T>5种重载,所以这里的Callbacks5种重载。

    (8).Verify验证

    用于测试mock对象的方法或属性是否被调用执行.也有很多重载:

    Verify()

    Verify(Expression<Action<T>>)

    Verify<TResult>(Expression<Func<T, TResult>>)

    Verify(Expression<Action<T>>, Times)

    Verify(Expression<Action<T>>, String)

    Verify<TResult>(Expression<Func<T, TResult>>, Times)

    Verify<TResult>(Expression<Func<T, TResult>>, String)

    Verify(Expression<Action<T>>, Times, String)

    Verify<TResult>(Expression<Func<T, TResult>>, Times, String)

    (9).VerifyAll验证

    在使用Verify方法时,只有被标记为可证实的(.Verifiable())的才可以验证。

     

     

     

     

     

     

  • 相关阅读:
    平时用到的Linux命令
    angular.element方法汇总
    CSS display:inline-block
    CSS:position:fixed使用(转)
    常见浏览器兼容性问题与解决方案【转】
    部分浏览器兼容问题
    php对应js math.random
    php stdclass转数组
    写在2016年末
    VirtualBox中Ubuntu 14.04屏幕分辨率不能设置的问题
  • 原文地址:https://www.cnblogs.com/huanxiaolu/p/6892549.html
Copyright © 2011-2022 走看看