如何在单元测试时隔离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 ] ...
随机推荐
- 前端基础——css
前端基础——css css的内容主要包括:盒子模型.定位.单位与取值.属性.选择器.
- python使用(三)
1.function_option.py2.function_code_option.py3.thread_option.py4.class_option.py5.threading_option.p ...
- (转)OpenSSL CVE-2016-0800 和 CVE-2016-0703 漏洞修复细节拾趣
原文:https://www.freebuf.com/vuls/97727.html 1. 引子 本来最近和360 Nirvan Team的DQ430愉快的参加某加密厂商的年度大会,结果openssl ...
- tomcat8 进入不了Manager App 界面 403 Access Denied
准备 1.注释掉context.xml中的value属性 使用下面的命令: vim /usr/local/tomcats/tomcat-daily/webapps/manager/META-INF/c ...
- JavaScript -- Select
-----053-Select.html----- <!DOCTYPE html> <html> <head> <meta http-equiv=" ...
- Java 范例 - 线程
创建线程 Java 中有以下三种方式创建线程,其中前两种无法获取返回值,而最后一种可以获取返回值. 实现 Runnable 接口 继承 Thread 类 通过 Callable.Future 接口配合 ...
- Java多线程同步集合--并发库高级应用
一.阻塞队列1.在多线程领域,所谓阻塞,在某些情况下会挂起线程,一旦条件满足,被挂起的线程又会自动被唤醒2.ArrayBlockingQueue(效率高)和LinkedBlockingQueue是两个 ...
- jdk8-stream-并行流的使用
使用jdk的stream, 可以非常方便的将串行改为并行 1, 判断是否质数 /** * 将一个stream改成简单的并行 */ @Test public void test1() { // 串行 , ...
- Visual Studio自带的的Developer Command Prompt对话框
简单了解Visual Studio的Developer Command Prompt VS2008的命令为:Visual Studio 2008 Command Prompt 目录是: 其详细信息如下 ...
- *2 FastCGI sent in stderr: "PHP message: PHP Parse error: syntax error, unexpected '[' in /application/nginx-1.6.3/html/zabbix/index.php on line 32" while reading response header from upstream, clien
今天呢想学习一下zabbix监控一下我的服务情况,然后就开始安装我的zabbix服务,首先LNMP环境准备好了,Nginx版本为1.6.3,php版本为5.3.27,MySQL版本为二进制包安装的5. ...