创建一个 seeJsonInDatabase 测试方法
Laravel 提供了 $this->seeJson()
and $this->seeInDatabase()
两个测试方法,一个用来测试JSON数据一个用来检测数据库中是否保有记录。这两个方法十分有用。然而Laravel本身却没有提供一个可以用来检测数据库中的保存JSON是否正确。
最近我在项目中需要在数据库中保存JSON字符,我需要在集成测试中测试数据库中的JSON字符串是否正确。所以我参考了seeJson和seeInDatabase的代码后,整合出来一个新的方法seeJsonInDatabase()
。
源代码如下,可以放入tests目录下的TestCase中使用:
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
......
public function seeJsonInDatabase($table,array $locatingData,$field,array $verifingData,$negate=false,$connection=null)
{
$database = $this->app->make('db');
$connection = $connection ?: $database->getDefaultConnection();
$row = $database->connection($connection)->table($table)->where($locatingData)->select($field)->get();
$row=collect($row)->last();
$json=$row->$field;
$method = $negate ? 'assertFalse' : 'assertTrue';
$actual = json_encode(Arr::sortRecursive(
(array) json_decode($json)
));
foreach (Arr::sortRecursive($verifingData) as $key => $value) {
$expected = $this->formatToExpectedJson($key, $value);
$this->{$method}(
Str::contains($actual, $expected),
($negate ? 'Found unexpected' : 'Unable to find')." JSON fragment [{$expected}] within [{$actual}]."
);
}
return $this;
}
代码的参数解释:
$this->seeJsonInDatabase(
"table", //表格
['id'=>3],//定位记录的条件,如果有多项,选用最后一条记录
"title", // 字段
["field in json"=>"value"], //JSON 中的字段和数据,使用方法见 seeJson
false,//断言否: false 用assertTrue, true 用assertFalse
'sqlite'//使用那个数据库的连接配置
);
如果只是要在默认连接下查找JSON的话,只要给出4个参数就可以了:
$this->seeJsonInDatabase(
"table",
['id'=>3],
"title",
["field in json"=>"value"]);
代码缺陷:
- 这段代码不是通过JSON找数据,而是先定位找到数据后,取出JSON来验证JSON的正确性。
- 如果找到了数据多于一条,只会选择最后一条进行验证。
:+1: MySQL 5.7 的 JSON 支持