laravel进行单元测试的时候如何模拟数据库以及mockery的调用
单元测试是独立的,所谓的独立是指有独立的运行容器,独立的数据库。
这样做有什么好处呢?
(1). 不会跟正常的容器产生冲突,继而影响正常业务。
(2). 数据库独立防止数据被修改影响单元测试结果。
这两天攻克了单元测试的两个问题:模拟数据库、mockery的调用。现在把原理解析一下。
1. 模拟数据库
那这样,我们来想一下。正常的创建一个数据库要有那些流程?
(1)定义表结构
(2)往表中插入数据
其实测试使用的模拟数据库总的来说也就这两个流程。
来来来,敲黑板,重点来了。

database目录下有三个文件夹,migrations中存储的是表结构文件,factories中存储的是创建模拟数据的方法,seeds没研究,暂时不知道干啥用的。
这个时候可能会有人问:创建表结构文件是什么鸡儿?它有啥用啊。
我们这样想一下:我们要创建模拟数据库,那数据库中肯定要有表吧。表长什么样子呢?你不给定义laravel怎么知道呢?那在哪里定义呢?就在migrations下面定义!!!
来给大家举个例子:

看见这个文件没?它就是定义表结构的地方。它长这个样子:

我们再仔细看看这个文件名:

哇,这名字这么长。还有日期,中间还有一串数字,让我怎么写嘛。
兄弟,别急。我有一计可保你平安。
在项目下面执行这句话:你就会得到你想要的结果
php artisan make:migration test --path=database/migrations/pandaRead
look here:

创建了新的文件,有木有,有木有。然后你就可以在up中写你表结构的定义了。
有同学可能会问这表里面的东西都是干啥的呀?作者云:内事不决问百度,外事不决问谷歌。
知道了为啥定义表结构和怎么设定表结构。
这个时候可能又会有兄弟问了:唉,你这个migrations下面为啥还有个pandaRead目录啊?你创建它干啥啊?
问的好!!!
一个大型的项目它所涉及到的数据库往往不止一个,而且各个数据库涉及到的业务往往不交叉,所以我们往往只会模拟一个数据库中的所有表。如果一次性的把所有数据库中的所有表都创建了,会很浪费资源。因此:给每个库定义一个文件夹,文件夹下面存储某个库下面的表结构文件,这样你在加载数据的时候可以根据文件夹把涉及到的所有表都一下子给创建了。
那又会有同学问了,什么时候创建表呢?表创建在哪里呢?
我就喜欢你这样问题多的小朋友!!!
来来来,诸位看官且把目光移到这里。

看到TestCase这个类了吗?它将会是你创建的所有测试文件的父类!!
那举个例子:

看到了没,所有的类都继承了TestCase这个类。
那我们是不是可以想:既然所有的类都继承了TestCase这个类,那我们的配置是不是可以写到TestCase这里呢?当然可以!!!
等等???什么配置,我还没反应过来怎么就讲到配置了呢?
小老弟,别急。来来来,看这里,思考这几个问题:
(1)我们的表创建在哪里呢?创建到文件里?数据库里?还是内存里?我们要在哪里告诉系统呢?
(2)刚才我们定义了表结构文件,但是定义了并没有加载啊。在哪里加载他们呢?
想明白了吗?这些东西我们都要告诉laravel,不然即使laravel再强大,它也无能为力啊!!!
那在哪里告诉它呢?敲黑板,敲黑板,重点来了哈。
我们来看看TestCase.php这个类中到底有什么东西。

创建表的地方,数据库连接的方式都在这里配置。
创建表没什么好讲的了,我们来讲讲数据库的连接方式:
config(['database.connections.mysql' => config('database.connections.testing')]);
这句话其实就是给数据库添加配置:在database配置文件中,connections.mysql的配置

这样数据库的配置就搞定了。
别急我们再看下这个方法,一层一层的剥离下去,我们看看它到底做了什么
parent::setUp();



最终其实它创建了一个新的容器。
优秀啊,优秀啊!!!这样你每执行一个单元测试的时候,都会创建一个新的容器,各个文件的单元测试之间就不会相互影响了。厉害啊
现在我们再来看看模拟数据:
这个时候可能会有人问:什么是模拟数据啊?你想啊,你测试是不是需要数据?数据谁来创建?你可以选择自己创建,同时你也可以选择交给机器去创建,那你要创建什么样的数据呢?在哪里定义呢?你创建一条数据可以自己创建,创建10条也可以自己创建,那你要创建1000条,10000条呢?还自己创建吗?这个时候你就需要机器来帮你做这件事情了!!
没错。就是在这里定义。举个例子:

它里面是长这个样子的。里面的数据根据你的需要自己配置。Generator可是很强大的啊啊啊啊啊啊!!!建议大家看看

诺,看见了没?给那个类创建什么数据都在这里面定义好了。那什么时候插入呢?

看见没,我们可以直接用工厂创建,然后最后可以直接插入到数据表中!!!读取数据的方式就和平时读取数据的方式一样,没什么区别了。
2. mockery
模拟数据库讲清楚了,那mockery呢?
什么叫mockery,什么时候用到mockery呢?
mockery......自己去查吧。
简单的说你可以将mock理解为替换掉类中的某个方法,或者替换掉某个类。
看这里,我们mock掉了一个类的某个方法,然后重新在容器中绑定这个类,这样容器中的类就被替换了,当我们测试的时候调用这个类的这个方法的时候,就直接按照我们mock的数据返回了,优秀啊!!!

本次分享,到这里就结束了,欢迎大家批评指正。
laravel进行单元测试的时候如何模拟数据库以及mockery的调用的更多相关文章
- php模拟数据库常用操作效果
test.php <?php header("Content-type:text/html;charset='utf8'"); error_reporting(E_ALL); ...
- SharedPreferences 存List集合,模拟数据库,随时存取
PS:SharedPreferences只要稍微学过一点就会用,他本身通过创建一个Editor对象,来存储提交,而editor可以存的格式为 他里面可以存一个Set<String> Set ...
- 在laravel环境下将图片存入MongoDB数据库
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...
- 单元测试系列之八:Sonar 数据库表关系整理一(续)
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 简介:Sonar平台是目前较为流行的静态代码扫描平台,为了便于使用以及自己二次开发,有必要对它的数据库结构进行学习 ...
- JavaEE学习之Spring Security3.x——模拟数据库实现用户,权限,资源的管理
一.引言 因项目需要最近研究了下Spring Security3.x,并模拟数据库实现用户,权限,资源的管理. 二.准备 1.了解一些Spring MVC相关知识: 2.了解一些AOP相关知识: 3. ...
- 单元测试系列之七:Sonar 数据库表关系整理一(rule相关)
更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/7510072.html 简介:Sonar ...
- C#全能数据库操作类及调用示例
C#全能数据库操作类及调用示例 using System; using System.Data; using System.Data.Common; using System.Configuratio ...
- BMP是在Bean中完成对数据库JDBC的各种调用
BMP是在Bean中完成对数据库JDBC的各种调用 CMP是由EJB容器自动完成对数据库的操作 会话Bean主要处理业务逻辑
- 如何使用T-SQL备份还原数据库及c#如何调用执行? C#中索引器的作用和实现。 jquery控制元素的隐藏和显示的几种方法。 localStorage、sessionStorage用法总结 在AspNetCore中扩展Log系列 - 介绍开源类库的使用(一) span<T>之高性能字符串操作实测
如何使用T-SQL备份还原数据库及c#如何调用执行? 准备材料:Microsoft SQL Server一部.需要还原的bak文件一只 一.备份 数据库备份语句:user master backup ...
随机推荐
- python 发送带附件的邮件
特别注意的地方:filespart.add_header("Content-Disposition","attachment",filename=file_na ...
- Spring中的事务操作
事务的特性 原子性:强调事务的不可分割. 一致性:事务的执行的前后数据的完整性保持一致. 隔离性:一个事务执行的过程中,不应该受到其他事务的干扰. 持久性:事务一旦结束,数据就持久化到数据库. 如果不 ...
- OCP-第三节课.md
一. dataguard stream 字节流技术: 二. 突然断电:触发实例恢复过程: 三. 宕机:赔钱 四. Redis.MQ(消息中间件.队列管理器.缓存)(内存数据库) 五. IBM MQ ...
- BMC ipmitool 对linux服务器进行IPMI管理
IPMI是智能型平台管理接口(Intelligent Platform Management Interface)的缩写,是管理基于 Intel结构的企业系统中所使用的外围设备采用的一种工业标准,该标 ...
- Golang--选择、循环语法总结
1.判断语句if 条件表达式没有括号 支持初始化表达式 初始化语句的变量自在本block内有效 if a,b,c := 1,2,3;a+b+c>6 { fmt.Println("hah ...
- laravel框架基础(1)---入门与介绍
1.安装laravel5.7 (composer )2018-12-28 11:59:02 [作者:struggler] Php的版本要求:php>=7.1.3 打开php OpenSSL扩展 ...
- 彻底解决(Microsoft Visual C++ 14.0 is required)的步骤123
之前要用协程gevent,安装pip install gevent包时遇到Microsoft Visual C++ 14.0 is required的报错提示,各种下载没有解决很头疼, 前两天安装sc ...
- visual studio code常用插件
1.auto close tag2.chinese language pack for visual studio code3.debugger for chrome4.docker5.html cs ...
- Linux+DDoS deflate 预防DDoS攻击
使用DDoS脚本防止DDoS攻击 使用DDoS脚本防止DDoS攻击: DDoS概述: 分布式拒绝服务(DDoS:Distributed Denial of Service)攻击,指借助于客户/服务 ...
- C# 使用lambda表达式过滤掉数组中的空字符串
使用lambda表达式过滤掉数组中的空字符串 KeyWord = KeyWord.Where(S => !string.IsNullOrEmpty(S)).ToArray();