在项目中需要对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. Form表单中不同的按钮进行不同的跳转

    本文参考:http://my.oschina.net/sallency/blog/300568 在开发工作共我们往往会遇到一个表单需要包含多个action不同的提交动作,这时候就不能在使用submit ...

  2. ASP.NET Core 与 .NET Core 演变与基础概述

    https://github.com/dotnet/corehttps://github.com/aspnet/home 今天看到 .NET Core 的改名计划,感觉跨平台的时代快要来了,从之前的 ...

  3. 为什么研发团队不适合量化KPI的绩效考核?

    研发团队(如果不是外包,不是机械性的活动)如果进行的是creative的有创造性的智力活动,那么应该不适合用量化KPI的绩效考核和激励,不应该用工时.bug数(难度大的bug可能多,测试人员可能没有经 ...

  4. IDEA中Git的使用基础

    场景概述 工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小袁 场景一:小张创建项目并提交到远程Git仓库 场景二:小袁从远程Git仓库上获取项目源码 ...

  5. 详解C#特性和反射(四)

    本篇内容是特性和反射的最后一篇内容,前面三篇文章: 详解C#特性和反射(一) 详解C#特性和反射(二) 详解C#特性和反射(三) 一.晚期绑定(Late Binding)是一种在编译时不知道类型及其成 ...

  6. Andrew Ng机器学习课程笔记(二)之逻辑回归

    Andrew Ng机器学习课程笔记(二)之逻辑回归 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7364636.html 前言 ...

  7. NHibernate 有好几种数据库查询方式

    NHibernate 有好几种数据库查询方式 1.原生SQL var employeeQuery = Database.Session .CreateSQLQuery("select * f ...

  8. 【PyTorch深度学习60分钟快速入门 】Part0:系列介绍

      说明:本系列教程翻译自PyTorch官方教程<Deep Learning with PyTorch: A 60 Minute Blitz>,基于PyTorch 0.3.0.post4 ...

  9. http缓存详解,http缓存推荐方案

    前言 通过本文,你将了解到http缓存机制是怎样的,no-cache到底有没有缓存,地址栏回车,F5,ctrl+F5的区别,以及当下较为推荐的缓存方案等. 自从和前端组的同事一起整了个前端扫盲计划,想 ...

  10. CTSC 2018 游记

    day0 李总提前一天放假,回家颓整理行李... 然而我... 早上:睡觉... 中午:睡觉... 晚上:睡觉去火车站... 吃了几把鸡,本来想带李总入坑,但他挥手拒绝然后被李总带进了炸金花的坑... ...