使用 Moq 测试.NET Core 应用 -- Mock 属性

第一篇文章, 关于Mock的概念介绍: http://www.javashuo.com/article/p-rjikmmye-ha.htmlhtml

第二篇文章, 关于方法Mock的介绍: http://www.javashuo.com/article/p-bbgioyks-mg.htmlgit

本文介绍Moq的使用.github

使用的代码: https://github.com/solenovex/Moq4-Tutorial-Code 里面的 03 Before 部分.单元测试

Mock属性

属性是指 get set property.测试

接着上文, 我在03 Before部分的代码里作了一些修改.spa

首先IPhysicalExamination接口添加了IsMedicalRoomAvailable属性:调试

其实现类:htm

属性方法内依然没有作实现.对象

 

添加的这个属性在业务上的意思就是体检室是否可使用. 若是不可使用的话, 那么球员的转会操做应该被推迟.blog

因此还须要为转会结果枚举添加一个推迟:

 

最后在转会审批逻辑里进行判断, 若是体检室不可用, 那么转会就被推迟:

 

在单元测试里对属性进行mock很是的简单:

 

这个测试也会经过的:

 

递归Mock

修改一下IPhysicalExamination接口, 造成一个多层嵌套的属性:

IPhysicalExamination --> IMedicalRoom --> IMedicalRoomStatus --> IsAvailable.

经过上面这一串来判断体检室是否可用.

 

相应的实现类也要修改:

 

转会审批方法里也要修改:

 

而在单元测试的方法里, 确定是报错的:

 

按照正常的思路, 咱们可能会这样作:

就是从内到外一层一层的mock.

这么作是没问题的, 测试也会经过:

 

可是这样作很麻烦, 而Moq则提供了一种简单的方式来处理这种多层的/递归的mock:

这样写便可. 测试一样会经过:

 

为属性设置默认值

可是, 问题来了, 我还有一些其它的单元测试方法, 它们也须要用到这个属性, 如今它们的状态是:

有的测试失败是由于其MockBehavior是Strict的, 而其它的失败则是由于里面出现了NullReferenceException.

 

针对这些状况, 咱们能够这样设定:

这样设置以后, 它会返回属性类型的默认值, 由于我没有设定返回值.

虽然测试依然不经过, 这是由于逻辑上的问题, 而不会抛出异常:

 

针对这种状况, 还有一种更好的办法. 咱们能够为mock对象设定默认值:

把DefaultValue的值设为DefaultValue.Mock.

可是DefaultValue这个属性只对引用类型起做用(对值类型不起做用), 像这种递归的mock, 它会递归的建立所需的引用类型, 可是最后的IsAvailable这个值类型是不起做用的.

测试:

由于最后一层是bool类型的, 是值类型, 因此上面的设置不起做用, 返回的是false. 因此测试没经过.

 

那我就把它改为string类型好了:

审批方法:

而后再调试测试:

string是引用类型, 可是mock的值依然是null...??!!??

这是由于string是一个sealed class, 而DefaultValue.Mock只对接口, 抽象类和非sealed的class起做用....

不过测试仍然是能够经过的, 由于我改逻辑了:

 

注意, 这个默认值只对宽松(Loose) mock, 起做用.针对Strict mock, 仍然须要设定最后一层属性的值.

 

属性值变化跟踪

须要添加一些代码, 首先添加一个枚举:

为接口添加属性:

实现类:

而后在审批类里, 我设置了这个属性的值:

 

上面的代码也就是说, 个人mock对象的某个属性在测试的时候它的值会发生变化. 而Moq能够记住这些mock属性的变化的值.....

 

新写一个测试:

这里使用mockObj.SetupProperty()方法来开始追踪属性. 这个测试会经过:

该方法也能够经过下面的写法来为被追踪的属性设置默认值:

mockExamination.SetupProperty(x => x.PhysicalGrade, PhysicalGrade.Failed);.

 

若是这个对象上有不少属性须要进行设置和追踪, 那么可使用:

mock.SetupAllProperties(); 这个方法:

 

注意, 这个方法应该最早调用, 不然的话其它的设置可能会被覆盖.

 

本文完成的代码在: https://github.com/solenovex/Moq4-Tutorial-Code 里面的03 After.

未完待续......

相关文章
相关标签/搜索