简体   繁体   中英

Using Crypt with Laravel phpunit tests

I am using phpunit with Laravel to perform some tests. I have a lot of database data that is encrypted.

In one of my tests I fill out a form, and once it is completed, the data is encrypted using Crypt::encrypt('data from field goes here') .

Here is the code:

$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')]);

I get the following error message:

Unable to find row in database table [requests] that matched attributes [{"first_name":"eyJpdiI6InFWbGJmSU9rR0NHMjFnMjR4QVVyalE9PSIsInZhbHVlIjoiaDBMcGNxYzdsRlhjNDd3M2E5OGxQbUVkaHhzdEpIOERDcytwQytzZUN4MD0iLCJtYWMiOiJlN2U2MzczYTlhMDgyYTMxOWJmMGQyZDU0MzFiMmZiZjhkMDM1ZjA2YWFhZGVkYTZhMGRkNGMzNDY0ZTAzMjZmIn0="}].

I tried to manually check to see if the record existed after being created and it did not show up. I remember reading something about data not persisting when running tests, so that would make sense... But are you able to think of any reasons why it wouldn't be able to find that record during the test?

The Crypt::encrypt() functionality does not create a reproducible hash. This is why you're not able to find the record, because the hash stored in the database will be different than the second hash you're looking for.

For example, below is the output from a php artisan tinker session:

>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IlU5bFFhV3JTWHozMklKbjFNc2VqVlE9PSIsInZhbHVlIjoieHZOK2ZSc0pNWlJWeUNYRktVNHc2dz09IiwibWFjIjoiOTI3YjY3MDI5OWJjMTU2M2RhMWFkYmNkOTJmMmE0OTU4MGE5MDNlNTk5NWZiOTgxNjA3Yjk1YTZiNTc1NjAwZCJ9"
>>> Illuminate\Support\Facades\Crypt::encrypt('hello');
=> "eyJpdiI6IjRHWDBvNkFQZmhJSUd0aFByZEFROGc9PSIsInZhbHVlIjoib00waTBpYThRZ3dkNTA5WWUxZWd0QT09IiwibWFjIjoiNzAwYzQ1NzliOTRiODg0M2Y3YTQ0YWIzNWY5NDcwNTJiMDJiYTgxZmJkM2U4MmQ2OWM2OTE3OGY4ZWVhNzgxMCJ9"

As you can see, the Crypt::encrypt() function run twice in a row for the same text produced different hashes.

You will need to find a different assertion for your test, such as retrieving the record from the database and checking if Crypt::decrypt($first_name) == 'FirstNameTest1' .

I know this is an old thread but I wanted to offer another solution that allowed using assertDatabaseHas .

$this->app->instance('encrypter', tap(Mockery::mock(), function ($mock) {
    $mock
        ->shouldReceive('encrypt')->once()
        ->with('111223333', true)
        ->andReturnArg(0);
}));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM