在项目中需要对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的更多相关文章

  1. SSM单元测试时出现:Failed to load ApplicationContext的一种可能解决办法

    SSM单元测试时出现: 严重: Caught exception while allowing TestExecutionListener [org.springframework.test.cont ...

  2. SpringAOP单元测试时找不到文件。

    ...applicationContext.xml] cannot be opened because it does not exist. 刚才在进行单元测试时,报这个错,我把它放到了src的某个包 ...

  3. 单元测试时使用Ninject的小问题

    主要是Kernel没有被释放,Ninject的Kernel必须调用IDispose释放.也有可能是静态类型在VS单元测试时无法被释放. 先记录下这个问题

  4. SSM项目使用junit单元测试时Mybaties通配符加载Mapper不能正常加载

    个人博客 地址:http://www.wenhaofan.com/article/20181108104133 问题描述 项目使用maven build 以及tomcat run能够正常运行,但是使用 ...

  5. 使用@RunWith(SpringJUnit4ClassRunner.class)进行单元测试时 报错 和 java.lang.NoSuchMethodError的解决方法

    1 使用@RunWith(SpringJUnit4ClassRunner.class)进行单元测试时,需要junit高版本和spring-test的高版本才支持,junit需要4.0以上的,sprin ...

  6. 单元测试(四)-隔离框架NSubstitute

    之前学习了单元测试的基础知识,以及桩对象和模拟对象的不同作用.但在实际应用中,往往不会直接手写桩对象或者模拟对象,而是使用隔离框架动态的创建这些对象,这可以让测试变得更简便.快捷,还可以更好地应对复杂 ...

  7. Unit Test单元测试时如何模拟HttpContext

    参考文章:http://blog.csdn.net/bclz_vs/article/details/6902638 http://www.cnblogs.com/PurpleTide/archive/ ...

  8. 单元测试或main方法 进行单元测试时 idea检查其他类的语法是否正确的去除方法

    在进行单元测试或者main方法时,在 运行/调试 设置中设置想要使用的测试单位的 before launch 即可

  9. springMVC+mybatis 进行单元测试时 main SqlSessionFactoryBean - Parsed configuration file: 'class path resource' 无限的读取xml文件

    今天终于写完的Dao层的操作,怀着无比激动的心情,进行单元测试,就在最后一个方法,对的就是最后一个方法,启动单元测试就会报以下错误: [2016-05-11 18:25:01,691] [WARN ] ...

随机推荐

  1. (转)python通过paramiko实现,ssh功能

    python通过paramiko实现,ssh功能 1 import paramiko 2 3 ssh =paramiko.SSHClient()#创建一个SSH连接对象 4 ssh.set_missi ...

  2. MySQL笔记(4)---表

    1.前言 上一章记录了MySQL中的一些文件组成,以及相关作用和参数配置,本章开始记录深层次的存储结构,以便更好理解MySQL的设计. 2.索引组织表 InnoDB中,表都是根据主键顺序组织存放的,这 ...

  3. 研究CondItem

  4. list string 互转

    List转字符串,用逗号隔开 List<string> list = new List<string>();list.Add("a");list.Add(& ...

  5. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(九):代码整理优化

    工程规划 为了统一配置和代码解耦,我们对代码重新进行了整理和规划. 重新规划后,代码结构如下: kitty-pom: 统一管理 Maven 版本,打包配置 kitty-common: 公共代码模块,主 ...

  6. CentOS 7通过RVM来安装指定版本的Ruby

    RVM也就是Ruby Version Manager,Ruby版本管理器 1.安装依赖库: yum install gcc-c++ patch readline readline-devel zlib ...

  7. AutowireCapableBeanFactory源码详解

    一.概述 对于想要拥有自动装配能力,并且想要把这种能力暴露给外部应用BeanFactory类需要实现此接口. 正常情况下不要使用此接口,应该更倾向于使用BeanFactory或者ListableBea ...

  8. Git 撤销与修改

    增补提交 git commit –C HEAD –a --amend -C表示复用指定提交的提交留言,这个例子中是HEAD,实际上可以指定其他有效的提交名称. 如果参数是小写的-c,就会打开预先设置好 ...

  9. PowerDesigner Constraint name uniqueness 错误

    使用PowerDesigner生成数据库脚本时报 Constraint name uniqueness 错误: 双击每行错误,发现外键引用的名字有重复的: 惯性去网上找解决办法,找到的主要是两个方法: ...

  10. JVM调优命令-jmap

    jmap JVM Memory Map命令用于生成heap dump文件,如果不使用这个命令,还可以使用-XX:+HeapDumpOnOutOfMemoryError参数来让虚拟机出现OOM的时候自动 ...