如何在单元测试时隔离ORM
如何在单元测试时隔离ORM
zhixin9001 发表于6个月前
如何在单元测试时隔离ORM
  • 发表于 6个月前
  • 阅读 148
  • 收藏 9
  • 点赞 0
  • 评论 2

腾讯云 技术升级10大核心产品年终让利>>>   

在项目中需要对DAL层进行单元测试,如果直接操作数据库,首先测试速度会大大下降,而且让单元测试直接使用外部依赖,很可能带来后续维护的不便,所以有必要对数据库隔离,然后单独测试DAL层。由于使用了ORM框架EF,就从EF入手。按照单元测试的思路,这是便在DAL层与EF之间找到或制造接缝,并从接缝处开始分割、注入。

 

一 基本思路

a) 有个专门的设计模式(Repository)可以解决这个问题,这种模式除了能很好的达成我目前隔离ORM以进行单元测试的目的,还允许方便地替换ORM和数据库,比如从EF换成Dapper、从SQL Server 换成MySQL。这看来是很好的方法,但有点复杂,没有弄明白。这儿是为了达到隔离ORM框架的目的,所以就借鉴Repository模式的思路,先来个简化版的,借用别人的图描述:

 

图片来源:http://www.cnblogs.com/zhaopei/p/UnitTesting.html

 

以前在DAL中直接操作EF,两者紧密耦合。拿操作Student实体来举例,重构后将EF相关的代码都封装到IStudentRepository接口后面,这样DAL中操作的是IStudentRepository接口的方法而不再是EF了,随后便可以用实现IStudentRepository接口的桩对象来替换EF了。

 

b) 具体的实现中,规定了IRepository<T>接口,这个接口定义了基本的增删改查操作

 

 

 

如果是与后台管理员相关的逻辑,AdminUserRepository会实现这个接口,Add方法如下,在这里会直接操作EF对象(FitDbContext)。

 

 

然后在AdminUserService中,将AdminUserRepository经过构造函数传入

 

 

AdminUserRepository是对EF操作的封装,因为它实现了IRepository接口,所以可以基于IRepository接口产生伪对象,而且这样的结构还允许在AdminUserRepository中实现缓存,这样来看,叫Repository真是太形象了,上层代码可以直接从仓库中拿数据,而不必关心数据是直接从数据库拿还是上次缓存的。经过这样的改造后,便可以方便地进行单元测试了。

 

 

 

 

二 隔离后的测试案例

下面是一些使用NUnit和NSubstitute的测试代码记录

a) 验证桩对象的int型返回值

 

 

b) 测试返回的IQueryable结果集

 

为了伪造IQueryable结果集花了不少功夫,最后终于知道可以用.AsQueryable()方法。

 

c) 如果要验证返回的实体是否相等,需要重写相关的Equals方法

 

在AreEqual可以指定“相等”的标准

 

共有 人打赏支持
粉丝 6
博文 81
码字总数 63852
评论 (2)
流浪汉8023
用mock不就可以了
zhixin9001

引用来自“liulanghan8023”的评论

用mock不就可以了
嗯嗯,我就是记录了引入接缝以创建mock或stub的过程
×
zhixin9001
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: