文档章节

如何在单元测试时隔离ORM

zhixin9001
 zhixin9001
发布于 2017/06/01 22:01
字数 687
阅读 177
收藏 9

在项目中需要对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可以指定“相等”的标准

 

© 著作权归作者所有

共有 人打赏支持
zhixin9001
粉丝 6
博文 100
码字总数 80837
作品 0
西安
私信 提问
加载中

评论(2)

zhixin9001
zhixin9001

引用来自“liulanghan8023”的评论

用mock不就可以了
嗯嗯,我就是记录了引入接缝以创建mock或stub的过程
流浪汉8023
流浪汉8023
用mock不就可以了
仓储(Repository)和工作单元模式(UnitOfWork)

仓储和工作单元模式 仓储模式 为什么要用仓储模式 通常不建议在业务逻辑层直接访问数据库。因为这样可能会导致如下结果: 重复的代码 编程错误的可能性更高 业务数据的弱类型 更难集中处理数...

JoeSnail
01/18
0
0
.NET Core TDD 前传: 编写易于测试的代码 -- 缝

有时候不是我们不想做单元测试, 而是这代码写的实在是没法测试.... 举个例子, 如果一辆汽车在产出后没完成测试, 那么没人敢去驾驶它. 代码也是一样的, 如果项目未能进行该做的测试, 那么客户...

solenovex
07/25
0
0
模拟是一种代码异味(软件编写)(第十二部分)

原文地址:Mocking is a Code Smell 原文作者:Eric Elliott 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:yoyoyohamapi 校对者:IridescentMia athena0304 (译注...

吴晓军
2017/12/10
0
0
使用模拟测试框架的 5 个理由

背景 研究人员和专家已经声明了敏捷和单元测试的主流.如果你所使用的正好在主流框架中那是个好消息。但是如果你的公司被夹在漩涡中间怎么办?现在你正在试图让你的公司加快速度并且对你的代码...

oschina
2013/07/24
2.5K
10
途牛原创|大话权限中心的PHP架构之道

序 权限管理是无线运营系统中的核心模块,通过访问控制策略的配置,来约定人与资源的访问关系。 本文着重讲解如何通过PHP来构建一个灵活、通用、安全的权限管理系统。 关于权限 首先我们来聊...

ftwbzhao
2016/05/12
33
0

没有更多内容

加载失败,请刷新页面

加载更多

09.ajax局部渲染---《Beetl视频课程》

本期视频实现分类实时获取; 内容简介:使用了局部渲染技术,实现分类的实时获取 一起学beetl目录:https://my.oschina.net/u/1590490?tab=newest&catalogId=6214598 作者:GK Beetl满足了更...

Gavin-King
12分钟前
1
0
同步访问共享的可变数据(66)

关键字synchronized 保证同一时刻,只有一个线程执行某一个方法或代码块 当一个对象被一个线程修改时,可以阻止其他线程看到其内部的不一致状态 正确的使用同步可以避免任何对象看到其不一致...

Java搬砖工程师
14分钟前
1
0
银行卡二要素真实性查询

验证用户的银行卡号、持卡人姓名是否真实。 示例代码: private static String host = "https://bank.market.alicloudapi.com";private static String path = "/bank2";private sta...

貔貅叔
18分钟前
1
0
iOS补位动画、沙漏效果、移动UITableViewCell、模拟贪吃蛇、拖拽进度等源码

iOS精选源码 JHAlertView - 一款黑白配色的HUD之沙漏效果 继承UIButton的自定义按钮SPButton 用递归算法实现iOS补位动画 iOS 长按移动UITableViewCell JHLikeButton - 有趣的点赞动画 兼容X...

Android爱开源
29分钟前
1
0
上币至iamToken

https://github.com/consenlabs/token-profile 点击Fork按钮,插入到自己的github项目中 cd /Users/shijun/Desktop/blockChain/iamToken git clone https://github.com/yellmi1983/token-pro......

八戒八戒八戒
32分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部