开篇
因为自身之前基本没写过什么单元测试用例, 感觉是一大憾事, 计划在接下来需求中, 体验下 TDD 方式编程, 特此做了一次简单的笔记.
因为我们使用的laravel框架, 在底层已经帮我们实现了很多细节的东西, 无缝集成了 PHPUnit, 所以使用起来还是比较简单的.
简单例子
如果构造我们的数据
我们的业务代码中经常有需要直接查业务库、操作库的需求, 如果经常的改变数据库数据, 好多时候因为数据不到位, 多表逻辑的话更改繁琐
修改业务代码逻辑, 提交代码还需要将测试代码移除, 过程容易将调试代码提交上线
如何在测试用例中避免数据干扰, 只专心关注代码逻辑, 推荐使用 laravel 的 Mockery::mock, 无侵入性设置返回值.
1. 首先我们封装个设置 mock 的类
所有的需要mock的方法, 都需要初始化称 mock 对象
protected function initMock($class)
{
$mock = \Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
}
2. 在执行service之前, 一定要先 mock 下指定的类来
这里我们mock初始化了 ClueRepository 类
$this->clueRepository = $this->initMock(\xx\ClueRepository::class);
3. 设置 mock 的类执行次数一次方法指定返回值为 20
使用上一步骤 mock 对象, 设置调用一次 getClueTotal 方法, 返回20数值
$this->clueRepository->shouldReceive('getClueTotal')
->once()
->andReturn(20);
4. 绑定我们要测试的 service 类
获取service的对象
$this->clueRecommendService = app(\xx\ClueRecommendService::class);
5. 执行真正的业务逻辑
$ret = $this->clueRecommendService->claimRecommendClue(['sale_uid' => 111, 'clue_id' => 2]);
6. 验证返回值
验证传入和传出是否一致
$this->assertEquals($this->saleUid, $ret['sale_uid']);
$this->assertEquals($this->clueId, $ret['clue_id']);
7. 执行测试用例
vendor/bin/phpunit tests/ExampleTest.php
异常
异常可以在方法上增加注释使用
/**
* @expectedException Exception
* @expectedExceptionCode 136
* @expectedExceptionMessage 线索
*
* @throws Exception
*/
声明上个方法依赖, return返回值, 作为此方法的参数
/**
* 声明依赖上个方法
* @depends testBasicExample
*
*/
public function testGetClueInfoService(array $ret)
{
$this->assertTrue(true);
}
构造测试数组
$data = [
'name' => 'ttt',
'data' => [
'test' => '小明',
],
];
一些常用方法
//跳过当前方法执行结果
$this->markTestSkipped();
//在数组中判定外层test是否存在
$this->assertArrayHasKey('test', $data); #false
//查找最外层值是否存在
$this->assertContains('ttt', $data); #true