文档章节

如何在单元测试时隔离ORM

zhixin9001
 zhixin9001
发布于 2017/06/01 22:01
字数 687
阅读 160
收藏 9
点赞 0
评论 2

在项目中需要对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
粉丝 5
博文 97
码字总数 76864
作品 0
西安
加载中

评论(2)

zhixin9001
zhixin9001

引用来自“liulanghan8023”的评论

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

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

JoeSnail ⋅ 01/18 ⋅ 0

【转】事务策略: 了解事务陷阱

前沿(笔者加):事务(Transaction)是每一个与数据库有关的系统开发与设计人员都会接触到的东西,在Java中,传统的直接使用JDBC的事务开始、提交、回滚的方式已经随着各种应用开发框架(尤...

晨曦之光 ⋅ 2012/03/09 ⋅ 0

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

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

吴晓军 ⋅ 2017/12/10 ⋅ 0

基于Hibernate的JPA2.0快速构建

前言 尽管现在开源的框架已经非常优秀,但是缺乏统一的标准有违软件开源的初衷,因此Sun公司的JCP组织发布了Java EE的JPA标准,并统一ORM规则、JPQL查询语言、子查询、高级查询和批量处理等操...

Barudisshu ⋅ 2014/09/17 ⋅ 0

途牛原创|大话权限中心的PHP架构之道

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

ftwbzhao ⋅ 2016/05/12 ⋅ 0

单元测试实践的主要问题与解决(7)

(承上篇) 这个底层函数返回的是一个对象指针,如何模拟呢?双击函数名,打开底层模拟器。 首先,在前置代码中定义对象并初始化。然后,在模拟值中填写这个对象的地址。 这是模拟的结果。 ...

dellfox ⋅ 2012/01/12 ⋅ 0

php 常用类总汇

图表库 下面的类库可以让你很简单就能创建复杂的图表和图片。当然,它们需要GD库的支持。 pChart - 一个可以创建统计图的库。 Libchart - 这也是一个简单的统计图库。 JpGraph - 一个面向对象...

万里虎 ⋅ 2014/12/03 ⋅ 0

20个非常有用的PHP类库

下面是一些非常有用的PHP类库,相信一定可以为你的WEB开发提供更好和更为快速的方法。 图表库 下面的类库可以让你很简的创建复杂的图表和图片。当然,它们需要GD库的支持。 pChart - 一个可以...

net ljx ⋅ 2011/03/30 ⋅ 0

spring事务管理(Transaction)

事务概述 数据库事务(Transaction) 指作为单个逻辑工作单元执行的一系列操作。将一组相关操作组合为一个要么全部成功要么全部失败的单元,使应用程序更加可靠。 事务必须满足ACID: n原子性(...

学-无止境 ⋅ 2016/09/03 ⋅ 0

Spring @Transactional 事务陷阱

Spring事务的传播行为 在service类前加上@Transactional,声明这个service所有方法需要事务管理。每一个业务方法开始时都会打开一个事务。 Spring默认情况下会对运行期例外(RunTimeException...

恋空御月 ⋅ 2016/07/26 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

个人博客的运营模式能否学习TMALL天猫质量为上?

心情随笔|个人博客的运营模式能否学习TMALL天猫质量为上? 中国的互联网已经发展了很多年了,记得在十年前,个人博客十分流行,大量的人都在写博客,而且质量还不错,很多高质量的文章都是在...

原创小博客 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 今天 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 今天 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部