Laravel (5.7) Тестирование базы данных
Вступление
Laravel предоставляет нам множество полезных инструментов, облегчающих тестирование наших приложений на основе баз данных. Во-первых, мы можем использовать помощник assertDatabaseHas, чтобы утверждать, что в базе данных существуют данные, соответствующие заданному набору критериев. Например, если мы хотим убедиться, что в таблице пользователей есть запись со значением электронной почты [email protected] , мы можем сделать следующее:
public function testDatabase()
{
// Make call to application...
$this->assertDatabaseHas('users', [
'email' => '[email protected]'
]);
}
Мы также можем использовать помощник assertDatabaseMissing, чтобы утверждать, что данные не существуют в базе данных.
Метод assertDatabaseHas и другие подобные помощники для удобства. мы можем использовать любой из встроенных в PHPUnit методов подтверждения в дополнение к нашим тестам.
Генерирующие заводы
Для создания фабрики вы можете использовать команду make: factory Artisan:
php artisan make:factory PostFactory
Новая фабрика помещается в каталог вашей базы данных / фабрики.
Опция --model может использоваться для указания названия модели, созданной на заводе. Эта опция предварительно заполняет сгенерированный файл фабрики заданной моделью:
php artisan make:factory PostFactory --model=Post
Сброс базы данных после каждого теста
Часто полезно сбрасывать базу данных после каждого теста, чтобы данные предыдущего теста не мешали последующим тестам. Признак RefreshDatabase использует наиболее оптимальный подход к переносу тестовой базы данных в зависимости от того, используете ли вы базу данных в памяти или традиционную базу данных. Когда вы используете черту в вашем тестовом классе, все будет обработано для вас:
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
class ExampleTest extends TestCase
{
use RefreshDatabase;
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$response = $this->get('/');
// ...
}
}
Написание Фабрики
При тестировании может потребоваться вставить несколько записей в вашу базу данных перед выполнением теста. Вместо того, чтобы вручную указывать значение каждого столбца при создании этих тестовых данных, Laravel позволяет определить набор атрибутов по умолчанию для каждой из ваших моделей Eloquent с использованием фабрик моделей. Если вы хотите начать, вы должны взглянуть на файл database / factories / UserFactory.php в вашем приложении. Этот файл содержит одно фабричное определение из коробки:
use Illuminate\Support\Str;
use Faker\Generator as Faker;
$factory->define(App\User::class, function (Faker $faker) {
return [
'name' => $faker->name,
'email' => $faker->unique()->safeEmail,
'email_verified_at' => now(),
'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret
'remember_token' => Str::random(10),
];
});
В Closure, который служит определением фабрики, вы можете вернуть значения тестов по умолчанию для всех атрибутов модели. Closure получает экземпляр библиотеки Faker PHP, которая позволит вам удобно генерировать различные виды случайных данных для тестирования.
Вы также можете создать дополнительные заводские файлы для каждой модели для лучшей организации. Например, вы можете создавать файлы UserFactory.php и CommentFactory.php в каталоге своей базы данных / фабрики. Все файлы в каталоге фабрики автоматически загружаются Laravel.
Заводские штаты
Состояния позволяют вам определять дискретные модификации, которые могут быть применены к вашим модельным фабрикам в любой комбинации. Например, ваша модель User может иметь состояние правонарушения, которое изменяет одно из значений атрибута по умолчанию. Вы можете определить свои преобразования состояния, используя метод состояния. Для простых состояний вы можете передать массив модификаций атрибутов:
$factory->state(App\User::class, 'delinquent', [
'account_status' => 'delinquent',
]);
В том случае, когда для вашего состояния требуется вычисление или экземпляр $ faker, вы можете использовать Closure для вычисления изменений атрибута состояния:
$factory->state(App\User::class, 'address', function ($faker) {
return [
'address' => $faker->address,
];
});
Фабричные обратные вызовы
Все обратные вызовы Factory регистрируются с использованием методов afterMaking и afterCreating. Эти обратные вызовы позволяют выполнять дополнительные задачи после создания или создания модели. Например, вы можете использовать обратные вызовы, чтобы связать дополнительные модели с созданной моделью:
$factory->afterMaking(App\User::class, function ($user, $faker) {
// ...
});
$factory->afterCreating(App\User::class, function ($user, $faker) {
$user->accounts()->save(factory(App\Account::class)->make());
});
Вы также можете определить обратные вызовы для заводских состояний:
$factory->afterMakingState(App\User::class, 'delinquent', function ($user, $faker) {
// ...
});
$factory->afterCreatingState(App\User::class, 'delinquent', function ($user, $faker) {
// ...
});
Использование Фабрики
Создание моделей
Сразу же после того, как вы определили свои фабрики, вы можете использовать глобальную фабричную функцию в своих тестах или исходных файлах для создания экземпляров модели. Итак, давайте рассмотрим несколько примеров создания моделей. Во-первых, мы будем использовать метод make для создания моделей, но не сохранять их в базе данных:
public function testDatabase()
{
$user = factory(App\User::class)->make();
// Use model in tests...
}
Вы также можете создать коллекцию из множества моделей или модели определенного типа:
// Creates three App\User instances...
$users = factory(App\User::class, 3)->make();
Применяя государства
Вы также можете применить любое из ваших состояний к моделям. Если вы хотите применить несколько преобразований состояний к моделям, вам нужно указать имя каждого состояния, которое вы хотите применить:
$users = factory(App\User::class, 5)->states('delinquent')->make();
$users = factory(App\User::class, 5)->states('premium', 'delinquent')->make();
Переопределение атрибутов
Если вы хотите переопределить некоторые значения по умолчанию ваших моделей, вы можете передать массив значений в метод make. Только указанные значения заменяются, в то время как остальные значения остаются установленными по умолчанию, как указано фабрикой:
$user = factory(App\User::class)->make([
'name' => 'Abigail',
]);
Сохраняющиеся модели
Метод create не только создает экземпляры модели, но и сохраняет их в базе данных, используя метод сохранения Eloquent:
public function testDatabase()
{
// Create a single App\User instance...
$user = factory(App\User::class)->create();
// Create three App\User instances...
$users = factory(App\User::class, 3)->create();
// Use model in tests...
}```
You can override attributes that are on the model by passing an array to the create method:
```
$user = factory(App\User::class)->create([
'name' => 'Abigail',
]);
Отношения
В приведенном ниже примере мы приложим отношение к некоторым созданным моделям. Когда вы используете метод create для создания нескольких моделей, будет возвращен экземпляр коллекции Eloquent, что позволит вам использовать любые удобные функции, предоставляемые коллекцией, такие как:
$users = factory(App\User::class, 3)
->create()
->each(function ($user) {
$user->posts()->save(factory(App\Post::class)->make());
});
Отношения и закрытие атрибутов
Вы также можете прикрепить отношения к моделям, используя атрибуты Closure в ваших определениях фабрики. Например, если вы хотите создать новый пользовательский экземпляр при создании сообщения, вы можете сделать следующее:
$factory->define(App\Post::class, function ($faker) {
return [
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
];
});
Эти замыкания также получат оцененный массив атрибутов фабрики, которая их определяет:
$factory->define(App\Post::class, function ($faker) {
return [
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
},
'user_type' => function (array $post) {
return App\User::find($post['user_id'])->type;
}
];
});
Доступные утверждения
Laravel предоставляет вам несколько утверждений базы данных для ваших тестов PHPUnit:
метод | Описание |
---|---|
$ this-> assertDatabaseHas ($ table, array $ data); | Утверждает, что таблица в базе данных содержит данные. |
$ this-> assertDatabaseMissing ($ таблица, массив $ data); | Утверждает, что таблица в базе данных не содержит данных. |
$ this-> assertSoftDeleted ($ таблица, массив $ data); | Утверждает, что данная запись была мягко удалена. |
Новый контент: Composer: менеджер зависимостей для PHP , R программирования