将 Crypt 与 Laravel phpunit 测试一起使用
Using Crypt with Laravel phpunit tests
我正在使用带有 Laravel 的 phpunit 来执行一些测试。我有很多加密的数据库数据。
在我的一个测试中,我填写了一张表格,一旦完成,数据就会使用 Crypt::encrypt('data from field goes here')
加密。
代码如下:
$this->visit('/requests/create')
->seePageIs('/requests/create')
->type('FirstNameTest1', 'first_name')
->press('Create Request')
->see('The request has been created.');
// Fails here
$this->seeInDatabase('requests', ['first_name' => Crypt::encrypt('FirstNameTest1')]);
我收到以下错误消息:
Unable to find row in database table [requests] that
matched attributes
[{"first_name":"eyJpdiI6InFWbGJmSU9rR0NHMjFnMjR4QVVyalE9PSIsInZhbHVlIjoiaDBMcGNxYzdsRlhjNDd3M2E5OGxQbUVkaHhzdEpIOERDcytwQytzZUN4MD0iLCJtYWMiOiJlN2U2MzczYTlhMDgyYTMxOWJmMGQyZDU0MzFiMmZiZjhkMDM1ZjA2YWFhZGVkYTZhMGRkNGMzNDY0ZTAzMjZmIn0="}].
我尝试手动检查记录创建后是否存在,但没有显示出来。我记得读过一些关于 运行 测试时数据不持久的内容,所以这是有道理的......但是你能想到在测试期间它无法找到该记录的任何原因吗?
Crypt::encrypt()
功能不会创建可重现的散列。这就是您找不到记录的原因,因为存储在数据库中的哈希值与您要查找的第二个哈希值不同。
例如,下面是 php artisan tinker
会话的输出:
>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IlU5bFFhV3JTWHozMklKbjFNc2VqVlE9PSIsInZhbHVlIjoieHZOK2ZSc0pNWlJWeUNYRktVNHc2dz09IiwibWFjIjoiOTI3YjY3MDI5OWJjMTU2M2RhMWFkYmNkOTJmMmE0OTU4MGE5MDNlNTk5NWZiOTgxNjA3Yjk1YTZiNTc1NjAwZCJ9"
>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IjRHWDBvNkFQZmhJSUd0aFByZEFROGc9PSIsInZhbHVlIjoib00waTBpYThRZ3dkNTA5WWUxZWd0QT09IiwibWFjIjoiNzAwYzQ1NzliOTRiODg0M2Y3YTQ0YWIzNWY5NDcwNTJiMDJiYTgxZmJkM2U4MmQ2OWM2OTE3OGY4ZWVhNzgxMCJ9"
如您所见,Crypt::encrypt()
函数 运行 连续两次针对同一文本生成不同的哈希值。
您将需要为您的测试找到不同的断言,例如从数据库中检索记录并检查是否 Crypt::decrypt($first_name) == 'FirstNameTest1'
。
我知道这是一个旧话题,但我想提供另一种允许使用 assertDatabaseHas
.
的解决方案
$this->app->instance('encrypter', tap(Mockery::mock(), function ($mock) {
$mock
->shouldReceive('encrypt')->once()
->with('111223333', true)
->andReturnArg(0);
}));
我正在使用带有 Laravel 的 phpunit 来执行一些测试。我有很多加密的数据库数据。
在我的一个测试中,我填写了一张表格,一旦完成,数据就会使用 Crypt::encrypt('data from field goes here')
加密。
代码如下:
$this->visit('/requests/create')
->seePageIs('/requests/create')
->type('FirstNameTest1', 'first_name')
->press('Create Request')
->see('The request has been created.');
// Fails here
$this->seeInDatabase('requests', ['first_name' => Crypt::encrypt('FirstNameTest1')]);
我收到以下错误消息:
Unable to find row in database table [requests] that matched attributes [{"first_name":"eyJpdiI6InFWbGJmSU9rR0NHMjFnMjR4QVVyalE9PSIsInZhbHVlIjoiaDBMcGNxYzdsRlhjNDd3M2E5OGxQbUVkaHhzdEpIOERDcytwQytzZUN4MD0iLCJtYWMiOiJlN2U2MzczYTlhMDgyYTMxOWJmMGQyZDU0MzFiMmZiZjhkMDM1ZjA2YWFhZGVkYTZhMGRkNGMzNDY0ZTAzMjZmIn0="}].
我尝试手动检查记录创建后是否存在,但没有显示出来。我记得读过一些关于 运行 测试时数据不持久的内容,所以这是有道理的......但是你能想到在测试期间它无法找到该记录的任何原因吗?
Crypt::encrypt()
功能不会创建可重现的散列。这就是您找不到记录的原因,因为存储在数据库中的哈希值与您要查找的第二个哈希值不同。
例如,下面是 php artisan tinker
会话的输出:
>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IlU5bFFhV3JTWHozMklKbjFNc2VqVlE9PSIsInZhbHVlIjoieHZOK2ZSc0pNWlJWeUNYRktVNHc2dz09IiwibWFjIjoiOTI3YjY3MDI5OWJjMTU2M2RhMWFkYmNkOTJmMmE0OTU4MGE5MDNlNTk5NWZiOTgxNjA3Yjk1YTZiNTc1NjAwZCJ9"
>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IjRHWDBvNkFQZmhJSUd0aFByZEFROGc9PSIsInZhbHVlIjoib00waTBpYThRZ3dkNTA5WWUxZWd0QT09IiwibWFjIjoiNzAwYzQ1NzliOTRiODg0M2Y3YTQ0YWIzNWY5NDcwNTJiMDJiYTgxZmJkM2U4MmQ2OWM2OTE3OGY4ZWVhNzgxMCJ9"
如您所见,Crypt::encrypt()
函数 运行 连续两次针对同一文本生成不同的哈希值。
您将需要为您的测试找到不同的断言,例如从数据库中检索记录并检查是否 Crypt::decrypt($first_name) == 'FirstNameTest1'
。
我知道这是一个旧话题,但我想提供另一种允许使用 assertDatabaseHas
.
$this->app->instance('encrypter', tap(Mockery::mock(), function ($mock) {
$mock
->shouldReceive('encrypt')->once()
->with('111223333', true)
->andReturnArg(0);
}));