Movatterモバイル変換


[0]ホーム

URL:


Manage your servers with freedom and control. Learn more about the new Forge
Skip to content

WARNING You're browsing the documentation for an old version of Laravel. Consider upgrading your project to Laravel 12.x .

Database Testing

Introduction

Laravel provides a variety of helpful tools to make it easier to test your database driven applications. First, you may use theassertDatabaseHas helper to assert that data exists in the database matching a given set of criteria. For example, if you would like to verify that there is a record in theusers table with theemail value of[email protected], you can do the following:

1publicfunctiontestDatabase()
2{
3// Make call to application...
4 
5$this->assertDatabaseHas('users', [
6'email'=>'[email protected]'
7 ]);
8}

You can also used theassertDatabaseMissing helper to assert that data does not exist in the database.

Of course, theassertDatabaseHas method and other helpers like it are for convenience. You are free to use any of PHPUnit's built-in assertion methods to supplement your tests.

Resetting The Database After Each Test

It is often useful to reset your database after each test so that data from a previous test does not interfere with subsequent tests.

Using Migrations

One approach to resetting the database state is to rollback the database after each test and migrate it before the next test. Laravel provides a simpleDatabaseMigrations trait that will automatically handle this for you. Simply use the trait on your test class and everything will be handled for you:

1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6use Illuminate\Foundation\Testing\WithoutMiddleware;
7use Illuminate\Foundation\Testing\DatabaseMigrations;
8use Illuminate\Foundation\Testing\DatabaseTransactions;
9 
10classExampleTestextendsTestCase
11{
12useDatabaseMigrations;
13 
14/**
15 * A basic functional test example.
16 *
17 *@returnvoid
18*/
19publicfunctiontestBasicExample()
20 {
21$response=$this->get('/');
22 
23// ...
24 }
25}

Using Transactions

Another approach to resetting the database state is to wrap each test case in a database transaction. Again, Laravel provides a convenientDatabaseTransactions trait that will automatically handle this for you:

1<?php
2 
3namespace Tests\Feature;
4 
5use Tests\TestCase;
6use Illuminate\Foundation\Testing\WithoutMiddleware;
7use Illuminate\Foundation\Testing\DatabaseMigrations;
8use Illuminate\Foundation\Testing\DatabaseTransactions;
9 
10classExampleTestextendsTestCase
11{
12useDatabaseTransactions;
13 
14/**
15 * A basic functional test example.
16 *
17 *@returnvoid
18*/
19publicfunctiontestBasicExample()
20 {
21$response=$this->get('/');
22 
23// ...
24 }
25}

By default, this trait will only wrap the default database connection in a transaction. If your application is using multiple database connections, you should define a$connectionsToTransact property on your test class. This property should be an array of connection names to execute the transactions on.

Writing Factories

When testing, you may need to insert a few records into your database before executing your test. Instead of manually specifying the value of each column when you create this test data, Laravel allows you to define a default set of attributes for each of yourEloquent models using model factories. To get started, take a look at thedatabase/factories/ModelFactory.php file in your application. Out of the box, this file contains one factory definition:

1$factory->define(App\User::class,function(Faker\Generator$faker) {
2static$password;
3 
4return [
5'name'=>$faker->name,
6'email'=>$faker->unique()->safeEmail,
7'password'=>$password?:$password=bcrypt('secret'),
8'remember_token'=>str_random(10),
9 ];
10});

Within the Closure, which serves as the factory definition, you may return the default test values of all attributes on the model. The Closure will receive an instance of theFaker PHP library, which allows you to conveniently generate various kinds of random data for testing.

Of course, you are free to add your own additional factories to theModelFactory.php file. You may also create additional factory files for each model for better organization. For example, you could createUserFactory.php andCommentFactory.php files within yourdatabase/factories directory. All of the files within thefactories directory will automatically be loaded by Laravel.

Factory States

States allow you to define discrete modifications that can be applied to your model factories in any combination. For example, yourUser model might have adelinquent state that modifies one of its default attribute values. You may define your state transformations using thestate method:

1$factory->state(App\User::class,'delinquent',function($faker) {
2return [
3'account_status'=>'delinquent',
4 ];
5});

Using Factories

Creating Models

Once you have defined your factories, you may use the globalfactory function in your tests or seed files to generate model instances. So, let's take a look at a few examples of creating models. First, we'll use themake method to create models but not save them to the database:

1publicfunctiontestDatabase()
2{
3$user=factory(App\User::class)->make();
4 
5// Use model in tests...
6}

You may also create a Collection of many models or create models of a given type:

1// Create three App\User instances...
2$users=factory(App\User::class,3)->make();

Applying States

You may also apply any of yourstates to the models. If you would like to apply multiple state transformations to the models, you should specify the name of each state you would like to apply:

1$users=factory(App\User::class,5)->states('delinquent')->make();
2 
3$users=factory(App\User::class,5)->states('premium','delinquent')->make();

Overriding Attributes

If you would like to override some of the default values of your models, you may pass an array of values to themake method. Only the specified values will be replaced while the rest of the values remain set to their default values as specified by the factory:

1$user=factory(App\User::class)->make([
2'name'=>'Abigail',
3]);

Persisting Models

Thecreate method not only creates the model instances but also saves them to the database using Eloquent'ssave method:

1publicfunctiontestDatabase()
2{
3// Create a single App\User instance...
4$user=factory(App\User::class)->create();
5 
6// Create three App\User instances...
7$users=factory(App\User::class,3)->create();
8 
9// Use model in tests...
10}

You may override attributes on the model by passing an array to thecreate method:

1$user=factory(App\User::class)->create([
2'name'=>'Abigail',
3]);

Relationships

In this example, we'll attach a relation to some created models. When using thecreate method to create multiple models, an Eloquentcollection instance is returned, allowing you to use any of the convenient functions provided by the collection, such aseach:

1$users=factory(App\User::class,3)
2->create()
3->each(function($u) {
4$u->posts()->save(factory(App\Post::class)->make());
5 });

Relations & Attribute Closures

You may also attach relationships to models using Closure attributes in your factory definitions. For example, if you would like to create a newUser instance when creating aPost, you may do the following:

1$factory->define(App\Post::class,function($faker) {
2return [
3'title'=>$faker->title,
4'content'=>$faker->paragraph,
5'user_id'=>function() {
6returnfactory(App\User::class)->create()->id;
7 }
8 ];
9});

These Closures also receive the evaluated attribute array of the factory that defines them:

1$factory->define(App\Post::class,function($faker) {
2return [
3'title'=>$faker->title,
4'content'=>$faker->paragraph,
5'user_id'=>function() {
6returnfactory(App\User::class)->create()->id;
7 },
8'user_type'=>function(array$post) {
9return App\User::find($post['user_id'])->type;
10 }
11 ];
12});

Available Assertions

Laravel provides several database assertions for yourPHPUnit tests:

MethodDescription
$this->assertDatabaseHas($table, array $data);Assert that a table in the database contains the given data.
$this->assertDatabaseMissing($table, array $data);Assert that a table in the database does not contain the given data.
$this->assertSoftDeleted($table, array $data);Assert that the given record has been soft deleted.

Laravel is the most productive way to
build, deploy, and monitor software.

Products

Packages

Resources

Partners


[8]ページ先頭

©2009-2025 Movatter.jp