第一篇文章, 关于Mock的概念介绍: http://www.javashuo.com/article/p-rjikmmye-ha.htmlhtml
本文介绍使用Moq来Mock方法.git
使用的代码: https://github.com/solenovex/Moq4-Tutorial-Code 里面的 02 Before 部分.github
紧接着上文中的例子. 上一篇文章, 我在单元测试的时候, 把依赖项设为null:函数
而后便出现了NullReferenceException, 致使测试没法正常运行.单元测试
首先应该作的是在TransferApproval的构造函数里判断参数是否为null, 若是为null的话应该抛出ArgumentNullException:测试
这是更恰当的异常.ui
这样的话, 在测试的时候, 抛出的就是ArgumentNullException了, 它能够更恰当的表达程序出现的问题:spa
如今咱们可使用mock版本的依赖项来代替null了:3d
上面的代码首先使用Moq建立了一个mock版本的IPhysicalExamination的实例.调试
而因为Moq对依赖项进行了包装, 因此要得到实际的mock依赖项, 咱们须要使用mockExamination.Object属性. 而这个属性的类型就是IPhysicalExamination.
另一个测试方法我也这么改一下, 然乎从新Build. Run All Tests:
仍是红色的, 但如今是测试没经过, 并非抛出异常.
测试没经过的意思就是期待值和实际返回值不符.
让咱们来调试一下这个测试, 我在TransferApproval类里面设置一个端点, 查看一下这个mock依赖项的方法返回值:
而后调试测试:
跑到断点
能够看到这个Mock版本依赖项的IsHealthy()方法的返回值是false.
我并无对这个Mock版本的IPhysicalExamination的IsHealthy()方法设定返回值, 正由于如此, 它才会返回它方法返回类型的默认值, 它的返回类型是bool, 而bool的默认值是false, 因此如今IsHealthy()方法在没有设定的状况下的返回值就是false.
而PhysicalExamination这个具体的实现类因为各类缘由致使尚未实现, 为了让它不妨碍咱们的单元测试, 我先设定让它在不管传进什么参数的状况下都会返回true.
从业务上来说就是假设全部转会球员均可以经过体检:
那么如今全部的测试都应该能够经过了:
这里用到了It这个类, 在Moq里, It这个类是用来作参数匹配的, it 就是"它"的意思, 它就表明须要被匹配的参数.
It.IsAny<T>(), 它表示传递给方法的参数的类型只要是T就能够, 值是任意的. 只要知足了这个条件, 那么方法的返回值就是后边Returns()方法里设定的值.
Moq 关于It类的文档: http://www.nudoq.org/#!/Packages/Moq/Moq/It
它有下面几种用法:
我认为经过方法名就能够知道这些方法的用途.
下面我修改一下该测试方法, 使用It其它几个方法:
其测试结果仍然是经过的.
Moq里面有Strict(严谨)和Loose(宽松) mock对象的概念, 固然也有不少人不喜欢这个概念.
在当前的测试方法里, TransferApproval依赖于Mock<IPhysicalExamination>, 并调用其IsHealthy()方法.
若是不对IsHealthy()方法进行任何设定的状况下, 方法会返回bool的默认值false, 这种就是loose(宽松) Mock.
在建立Mock对象的时候, 还可选传递一个MockBehavior这个参数.
MockBehavior是一个枚举, 它有三个值:
若是上例使用Strict Mock, 那么将会抛出Exception:
下面我把一个测试改成Strict Mock, 并取消了对IsHealthy()方法的设置:
而测试时会抛出MockException:
在对方法进行设置后, 测试就会经过:
能够感受到:
Loose Mock, 能够少写一些设定代码, 能够返回默认值, 不易让测试中断
Strict Mock, 须要写跟多的设定代码, 每一个被调用的方法都须要进行设定, 因此也更容易让测试中断.
Moq的建议是: 大多数状况下应该使用Loose Mock, 只有特殊须要的时候才去使用Strict Mock.
修改一下TransferApproval类的转会审批方法:
此次使用的是带有out参数的IsHealthy()方法.
创建一个测试方法, 并设定这个带有out参数的方法:
很简单, 测试会经过:
完成的代码在: https://github.com/solenovex/Moq4-Tutorial-Code 02 After
未完待续....