如何在单元测试时隔离ORM
在项目中需要对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可以指定“相等”的标准
如何在单元测试时隔离ORM的更多相关文章
- SSM单元测试时出现:Failed to load ApplicationContext的一种可能解决办法
SSM单元测试时出现: 严重: Caught exception while allowing TestExecutionListener [org.springframework.test.cont ...
- SpringAOP单元测试时找不到文件。
...applicationContext.xml] cannot be opened because it does not exist. 刚才在进行单元测试时,报这个错,我把它放到了src的某个包 ...
- 单元测试时使用Ninject的小问题
主要是Kernel没有被释放,Ninject的Kernel必须调用IDispose释放.也有可能是静态类型在VS单元测试时无法被释放. 先记录下这个问题
- SSM项目使用junit单元测试时Mybaties通配符加载Mapper不能正常加载
个人博客 地址:http://www.wenhaofan.com/article/20181108104133 问题描述 项目使用maven build 以及tomcat run能够正常运行,但是使用 ...
- 使用@RunWith(SpringJUnit4ClassRunner.class)进行单元测试时 报错 和 java.lang.NoSuchMethodError的解决方法
1 使用@RunWith(SpringJUnit4ClassRunner.class)进行单元测试时,需要junit高版本和spring-test的高版本才支持,junit需要4.0以上的,sprin ...
- 单元测试(四)-隔离框架NSubstitute
之前学习了单元测试的基础知识,以及桩对象和模拟对象的不同作用.但在实际应用中,往往不会直接手写桩对象或者模拟对象,而是使用隔离框架动态的创建这些对象,这可以让测试变得更简便.快捷,还可以更好地应对复杂 ...
- Unit Test单元测试时如何模拟HttpContext
参考文章:http://blog.csdn.net/bclz_vs/article/details/6902638 http://www.cnblogs.com/PurpleTide/archive/ ...
- 单元测试或main方法 进行单元测试时 idea检查其他类的语法是否正确的去除方法
在进行单元测试或者main方法时,在 运行/调试 设置中设置想要使用的测试单位的 before launch 即可
- springMVC+mybatis 进行单元测试时 main SqlSessionFactoryBean - Parsed configuration file: 'class path resource' 无限的读取xml文件
今天终于写完的Dao层的操作,怀着无比激动的心情,进行单元测试,就在最后一个方法,对的就是最后一个方法,启动单元测试就会报以下错误: [2016-05-11 18:25:01,691] [WARN ] ...
随机推荐
- odoo开发笔记 -- 模型一对多tree视图弹窗效果实现
实现效果参考: 1. 开发者模式 -- 设置 -- 工作流 -- 编辑 -- 添加项目 2. 会计模块 -- 管理 -- 付款条款 -- 编辑/创建 实现方式,很简单.只要视图界面写个一对多关联字段就 ...
- VM虚拟机装centos无法自动获取IP的解决方法
在虚拟机中使用ip addr 查看网卡 可以看到这个ens33,可能每台机器的名称不一样 然后找到/etc/sysconfig/network-scripts/ifcfg-eth33 编辑此文件 vi ...
- 执行bin/hdfs haadmin -transitionToActive nn1时出现,Automatic failover is enabled for NameNode at bigdata-pro02.kfk.com/192.168.80.152:8020 Refusing to manually manage HA state的解决办法(图文详解)
不多说,直接上干货! 首先, 那么,你也许,第一感觉,是想到的是 全网最详细的Hadoop HA集群启动后,两个namenode都是standby的解决办法(图文详解) 这里,nn1,不多赘述了.很简 ...
- MVC源码分析 - Authorize授权过滤器
从 上一篇 其实能看到, 程序执行的过滤器, 有四种 : 过滤器类型 接口 描述 Authorization IAuthorizationFilter 此类型(或过滤器)用于限制进入控制器或控制器的某 ...
- ActiveMQ——activemq的报错见解javax.jms.JMSException: Software caused connection abort: recv failed
activeMQ出现javax.jms.JMSException: Software caused connection abort: recv failed的问题解决 一直找不到原因,原来是在本地的 ...
- 3D转弯保护区长啥样?
3D转弯保护区长啥样? 2015-12-06 刘崇军 风螺旋线 在课本中.规范中看到的转弯保护区一直是平面化的样子.我们知道副区是由主区外扩而成,但具体怎样精确外扩无从知晓:我们知道主区边界至副区边界 ...
- C# ABP - 创建自己的模块
本篇文章介绍怎么创建自己的模块,并且使用依赖注入方法进行模块间的无缝结合. 我们创建一下自己的一个会员模块,针对不同的系统都可以用.你们可以看看我是怎么做的,或者从中得到启发. 目录 1.开始创建项目 ...
- ASP.NET Core (二):入门
上一篇:ASP.NET Core(一):简介 下一篇:(待续) 英文原版:Getting Started 1. 安装 .NET Core 2. 创建 .NET Core 项目 在命令提示符窗口输入命令 ...
- Java基础——Servlet(一)
在学习Servlet之前,需要首先学习一些关联性的知识. 一.动态网页程序 动态网页:它是网页中的偏功能性的部分也是最重要的部分.它不是我们平时所看见的页面特效,展示的效果.而是,一种交互行为.比如, ...
- 【Linux】rpm常用命令及rpm参数介绍
RPM是RedhatPackageManager的缩写,是由RedHat公司开发的软件包安装和管理程序,同Windows平台上的Uninstaller比较类似.使用RPM,用户可以自行安装和管理Lin ...