イントロダクションIntroduction
Laravelはユニットテストも考慮して構築されています。実際、PHPUnitをサポートしており、最初から含まれています。アプリケーションのためにphpunit.xml
ファイルも最初から準備されています。さらにフレームワークはアプリケーションを記述的にテストするために便利なヘルパメソッドも持っています。Laravel is built with testing in mind. In fact, support for testing with PHPUnit is included out of the box, and a phpunit.xml
file is already setup for your application. The framework also ships with convenient helper methods allowing you to expressively test your applications.
ExampleTest.php
ファイルがtests
ディレクトリに提供されています。新しいLaravelアプリケーションをインストールした後、そのままphpunit
をコマンドラインで実行し試してみてください。An ExampleTest.php
file is provided in the tests
directory. After installing a new Laravel application, simply run phpunit
on the command line to run your tests.
テスト動作環境Test Environment
テスト実行時にLaravelは、設定環境を自動的にtesting
へセットします。そしてLaravelはセッションととキャッシュの設定ファイルをテスト環境で呼び出します。両方のドライバはテスト環境ではarray
にセットされます。つまりデータはテストを実行している間のみ存在しているということです。When running tests, Laravel will automatically set the configuration environment to testing
. Laravel automatically configures the session and cache to the array
driver while testing, meaning no session or cache data will be persisted while testing.
必要であれば他のテスト設定環境を自由に作成することもできます。testing
動作環境変数はphpunit.xml
の中で設定されています。テスト実行前には、config:clear
Artisanコマンドを実行し、設定キャッシュをクリアするのを忘れないでください。You are free to create other testing environment configurations as necessary. The testing
environment variables may be configured in the phpunit.xml
file, but make sure to clear your configuration cache using the config:clear
Artisan command before running your tests!
テストの定義と実行Defining & Running Tests
新しいテストケースを作成するには、make:test
Artisanコマンドを使います。To create a new test case, use the make:test
Artisan command:
php artisan make:test UserTest
上記のコマンドにより、tests
ディレクトリ中に新しいUserTest
クラスが設置されます。それから、いつもの通りPHPUnitを使ってテストメソッドを定義してください。テストを実行するには、ただターミナルでphpunit
コマンドを実行するだけです。This command will place a new UserTest
class within your tests
directory. You may then define test methods as you normally would using PHPUnit. To run your tests, simply execute the phpunit
command from your terminal:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UserTest extends TestCase
{
/**
* 基本的なテスト例
*
* @return void
*/
public function testExample()
{
$this->assertTrue(true);
}
}
注意:
setUp
メソッドを定義する場合はparent::setUp
を確実に呼び出してください。Note: If you define your ownsetUp
method within a test class, be sure to callparent::setUp
.
アプリケーションのテストApplication Testing
Laravelはアプリケーションに送るHTTPリクエストの作成、出力の検査、さらにフォームの入力もスラスラと書けるAPIを提供しています。例としてtests
ディレクトリに含まれるExampleTest.php
ファイルを見てください。Laravel provides a very fluent API for making HTTP requests to your application, examining the output, and even filling out forms. For example, take a look at the ExampleTest.php
file included in your tests
directory:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->visit('/')
->see('Laravel 5')
->dontSee('Rails');
}
}
visit
メソッドはアプリケーションに対するGET
リクエストを作成します。see
メソッドは指定されたテキストがアプリケーションから返されるレスポンスの中に存在することをアサートします。dontSee
メソッドは指定したテキストがアプリケーションレスポンスの中へ返されていないことをアサートします。これはLaravelで使用できる最も基本的なアプリケーションテストです。The visit
method makes a GET
request into the application. The see
method asserts that we should see the given text in the response returned by the application. The dontSee
method asserts that the given text is not returned in the application response. This is the most basic application test available in Laravel.
アプリケーションとの関わりInteracting With Your Application
もちろんシンプルに指定したレスポンスの中にテキストが現れるかアサートする以上のことが可能です。リンクのクリックとフォームの埋め込みを見てみましょう。Of course, you can do much more than simply assert that text appears in a given response. Let's take a look at some examples of clicking links and filling out forms:
リンクのクリックClicking Links
このテストではアプリケーションへのリクエストを作成し、帰ってきたレスポンス中のリンクを「クリック」、それから指定されたURIに到達することをアサートします。たとえば"About Us"のテキスト値を持つレスポンスの中のリンクがあると仮定しましょう。In this test, we will make a request to the application, "click" a link in the returned response, and then assert that we landed on a given URI. For example, let's assume there is a link in our response that has a text value of "About Us":
<a href="/about-us">About Us</a>
では、このリンクをクリックし、正しいページに到達したことをアサートしましょう。Now, let's write a test that clicks the link and asserts the user lands on the correct page:
public function testBasicExample()
{
$this->visit('/')
->click('About Us')
->seePageIs('/about-us');
}
フォームの埋め込みWorking With Forms
Laravelはさらにフォームをテストするために多くのメソッドを提供しています。type
、select
、check
、attach
、press
メソッドはフォーム入力の全てを操作させてくれます。たとえば、アプリケーションの登録ページにこのフォームがあると考えてください。Laravel also provides several methods for testing forms. The type
, select
, check
, attach
, and press
methods allow you to interact with all of your form's inputs. For example, let's imagine this form exists on the application's registration page:
<form action="/register" method="POST">
{{ csrf_field() }}
<div>
Name: <input type="text" name="name">
</div>
<div>
<input type="checkbox" value="yes" name="terms"> Accept Terms
</div>
<div>
<input type="submit" value="Register">
</div>
</form>
このフォームを完全に埋め、結果を確認するテストが書けます。We can write a test to complete this form and inspect the result:
public function testNewUserRegistration()
{
$this->visit('/register')
->type('Taylor', 'name')
->check('terms')
->press('Register')
->seePageIs('/dashboard');
}
もちろん、フォームにラジオボタンやドロップボックスのような他の入力が含まれていても、同様にそうしたフィールドを簡単に埋めることができます。フォーム操作メソッドのリストを見てください。Of course, if your form contains other inputs such as radio buttons or drop-down boxes, you may easily fill out those types of fields as well. Here is a list of each form manipulation method:
メソッドMethod | 説明Description |
---|---|
$this->type($text, $elementName) $this->type($text, $elementName) |
指定したフィールドに「タイプ」します。"Type" text into a given field. |
$this->select($value, $elementName) $this->select($value, $elementName) |
ラジオボタンかドロップダウンフィールドを「選択」します。"Select" a radio button or drop-down field. |
$this->check($elementName) $this->check($elementName) |
チェックボックスフィールドを「チェック」します。"Check" a checkbox field. |
$this->uncheck($elementName) $this->uncheck($elementName) |
"Uncheck" a checkbox field."Uncheck" a checkbox field. |
$this->attach($pathToFile, $elementName) $this->attach($pathToFile, $elementName) |
フォームにファイルを「添付」します。"Attach" a file to the form. |
$this->press($buttonTextOrElementName) $this->press($buttonTextOrElementName) |
指定したテキストか名前のボタンを「押し」ます。"Press" a button with the given text or name. |
ファイル添付操作Working With Attachments
フォームにfile
入力タイプが含まれているならば、attach
メソッドを使いフォームにファイルを添付できます。If your form contains file
input types, you may attach files to the form using the attach
method:
public function testPhotoCanBeUploaded()
{
$this->visit('/upload')
->type('File Name', 'name')
->attach($absolutePathToFile, 'photo')
->press('Upload')
->see('Upload Successful!');
}
JSON APIのテストTesting JSON APIs
さらにLaravelはJSON APIとそれらのレスポンスをテストするために、多くのヘルパも用意しています。たとえば、get
、post
、put
、patch
、delete
メソッドは各HTTP動詞でのリクエストを発行するために使用します。また簡単にデータとヘッダをメソッドに渡すこともできます。手始めに、/user
に対するPOST
リクエストを作成し、JSONフォーマットで指定指定した配列が返ってくることをアサートするテストを書いてみましょう。Laravel also provides several helpers for testing JSON APIs and their responses. For example, the get
, post
, put
, patch
, and delete
methods may be used to issue requests with various HTTP verbs. You may also easily pass data and headers to these methods. To get started, let's write a test to make a POST
request to /user
and assert that a given array was returned in JSON format:
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->json('POST', '/user', ['name' => 'Sally'])
->seeJson([
'created' => true,
]);
}
}
seeJson
メソッドは渡された配列をJSONに変換します。次にそのJSONが、JSONレスポンス全体のいずれかに現れるかを確認します。ですから、他のプロパティーがJSONレスポンスに含まれていたとしても、指定した部分が存在する限り、テストはパスします。The seeJson
method converts the given array into JSON, and then verifies that the JSON fragment occurs anywhere within the entire JSON response returned by the application. So, if there are other properties in the JSON response, this test will still pass as long as the given fragment is present.
JSONと一致するか厳格に検証Verify Exact JSON Match
指定した配列がアプリケーションから返されるJSONと厳格に一致するかを確認したい場合は、seeJsonEquals
メソッドを使用してください。If you would like to verify that the given array is an exact match for the JSON returned by the application, you should use the seeJsonEquals
method:
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->json('POST', '/user', ['name' => 'Sally'])
->seeJsonEquals([
'created' => true,
]);
}
}
JSON構造の合致Verify Structural JSON Match
それには、seeJsonStructure
メソッドを使い、ネストしたキーのリストを渡します。It is also possible to verify that a JSON response adheres to a specific structure. For this, you should use the seeJsonStructure
method and pass it a list of (nested) keys:
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->get('/user/1')
->seeJsonStructure([
'name',
'pet' => [
'name', 'age'
]
]);
}
}
上の例ではname
および、name
とage
を持つネストしたpet
オブジェクトを受け取ることを期待しています。seeJsonStructure
は、レスポンスが余計なキーを含んていても失敗しません。たとえば、pet
がweight
属性を持っていても、テストをパスします。The above example illustrates an expectation of receiving a name
and a nested pet
object with its own name
and age
. seeJsonStructure
will not fail if additional keys are present in the response. For example, the test would still pass if the pet
had a weight
attribute.
*
を使い、戻ってきたJSON構造がリストを持っていること、そして各リストが最低でも持っている属性を指定することもできます。You may use the *
to assert that the returned JSON structure has a list where each list item contains at least the attributes found in the set of values:
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
// 各ユーザはid、name、email属性を最低でも持っていることを宣言
$this->get('/users')
->seeJsonStructure([
'*' => [
'id', 'name', 'email'
]
]);
}
}
*
記述法はネストもできます。次の例の場合、JSONレスポンスの各ユーザは指定されている属性を持っており、各ユーザの各ペットも指定されている属性を持っていることを宣言します。You may also nest the *
notation. In this case, we will assert that each user in the JSON response contains a given set of attributes and that each pet on each user also contains a given set of attributes:
$this->get('/users')
->seeJsonStructure([
'*' => [
'id', 'name', 'email', 'pets' => [
'*' => [
'name', 'age'
]
]
]
]);
セッション/認証Sessions / Authentication
Laravelはテスト時にセッションを操作するたくさんのヘルパも提供しています。1つ目は指定した配列をセッションに保存するwithSession
メソッドです。これはアプリケーションのリクエストをテストする前に、データをセッションにロードしたい場合に便利です。Laravel provides several helpers for working with the session during testing. First, you may set the session data to a given array using the withSession
method. This is useful for loading the session with data before testing a request to your application:
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$this->withSession(['foo' => 'bar'])
->visit('/');
}
}
もちろん認証済みのユーザのようなユーザ状態をセッションへ保持するのは一般的です。actingAs
ヘルパメソッドは現在認証済みのユーザを指定する簡単な手段を提供します。たとえば、モデルファクトリでユーザを生成し、認証してみましょう。Of course, one common use of the session is for maintaining user state, such as the authenticated user. The actingAs
helper method provides a simple way to authenticate a given user as the current user. For example, we may use a model factory[#model-factories] to generate and authenticate a user:
<?php
class ExampleTest extends TestCase
{
public function testApplication()
{
$user = factory(App\User::class)->create();
$this->actingAs($user)
->withSession(['foo' => 'bar'])
->visit('/')
->see('Hello, '.$user->name);
}
}
ユーザの認証にどのガードを使用するかを指定したい場合、actingAs
メソッドの第2引数にガード名を渡します。You may also specify which guard should be used to authenticate the given user by passing the guard name as the second argument to the actingAs
method:
$this->actingAs($user, 'backend')
ミドルウェアの無効化Disabling Middleware
アプリケーションをテストするとき、いくつかのテストではミドルウェアを無効にするほうが便利だと気がつくでしょう。これによりミドルウェアに関わらずにルートやコントローラーのテストが可能になります。LaravelはシンプルなWithoutMiddleware
トレイトを用意しており、これを使えば自動的にテストクラスのミドルウェアを無効にできます。When testing your application, you may find it convenient to disable middleware[/docs/{{version}}/middleware] for some of your tests. This will allow you to test your routes and controller in isolation from any middleware concerns. Laravel includes a simple WithoutMiddleware
trait that you can use to automatically disable all middleware for the test class:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
use WithoutMiddleware;
//
}
いくつかのテストメソッドだけでミドルウェアを無効にしたい場合は、withoutMiddleware
メソッドをテストメソッドの中で呼び出してください。If you would like to only disable middleware for a few test methods, you may call the withoutMiddleware
method from within the test methods:
<?php
class ExampleTest extends TestCase
{
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->withoutMiddleware();
$this->visit('/')
->see('Laravel 5');
}
}
カスタムHTTPリクエストCustom HTTP Requests
アプリケーションに対してカスタムHTTPリクエストを作成し、完全なIlluminate\Http\Response
オブジェクトを取得したい場合は、call
メソッドを使ってください。If you would like to make a custom HTTP request into your application and get the full Illuminate\Http\Response
object, you may use the call
method:
public function testApplication()
{
$response = $this->call('GET', '/');
$this->assertEquals(200, $response->status());
}
POST
やPUT
、PATCH
リクエストの場合、そのリクエストに入力データの配列を渡すことができます。もちろん、このデーターはRequestインスタンスを使用し、ルートやコントローラーで使用できます。If you are making POST
, PUT
, or PATCH
requests you may pass an array of input data with the request. Of course, this data will be available in your routes and controller via the Request instance[/docs/{{version}}/requests]:
$response = $this->call('POST', '/user', ['name' => 'Taylor']);
PHPUnitのアサートPHPUnit Assertions
PHPUnitテスト用に、数多くの追加アサートメソッドをLaravelは提供しています。Laravel provides several additional assertion methods for PHPUnit[https://phpunit.de/] tests:
メソッドMethod | 説明Description |
---|---|
->assertResponseOk(); ->assertResponseOk(); |
クライアントのレスポンスがOKのステータスコードを受け取ることを宣言Assert that the client response has an OK status code. |
->assertResponseStatus($code); ->assertResponseStatus($code); |
クライアントのレスポンスが指定したコードであることを宣言Assert that the client response has a given code. |
->assertViewHas($key, $value = null); ->assertViewHas($key, $value = null); |
レスポンスのビューに指定したデータが含まれていることを宣言Assert that the response view has a given piece of bound data. |
->assertViewHasAll(array $bindings); ->assertViewHasAll(array $bindings); |
ビューが指定したデータのリストを持っていることを宣言Assert that the view has a given list of bound data. |
->assertViewMissing($key); ->assertViewMissing($key); |
ビューが指定したデータを含んでいないことを宣言Assert that the response view is missing a piece of bound data. |
->assertRedirectedTo($uri, $with = []); ->assertRedirectedTo($uri, $with = []); |
クライアントが指定したURIへリダイレクトすることを宣言Assert whether the client was redirected to a given URI. |
->assertRedirectedToRoute($name, $parameters = [], $with = []); ->assertRedirectedToRoute($name, $parameters = [], $with = []); |
クライアントが指定したルートへリダイレクトされることを宣言Assert whether the client was redirected to a given route. |
->assertRedirectedToAction($name, $parameters = [], $with = []); ->assertRedirectedToAction($name, $parameters = [], $with = []); |
クライアントが指定したアクションへリダイレクトすることを宣言Assert whether the client was redirected to a given action. |
->assertSessionHas($key, $value = null); ->assertSessionHas($key, $value = null); |
セッションが指定した値を持つことを宣言Assert that the session has a given value. |
->assertSessionHasAll(array $bindings); ->assertSessionHasAll(array $bindings); |
セッションが指定したリストを持つことを宣言Assert that the session has a given list of values. |
->assertSessionHasErrors($bindings = [], $format = null); ->assertSessionHasErrors($bindings = [], $format = null); |
セッションにエラー情報があることを宣言Assert that the session has errors bound. |
->assertHasOldInput(); ->assertHasOldInput(); |
セッションが直前の入力を持つことを宣言Assert that the session has old input. |
->assertSessionMissing($key); ->assertSessionMissing($key); |
セッションが指定したキーを持っていないことを宣言Assert that the session is missing a given key. |
データベースとの関わりWorking With Databases
Laravelではさらに、データベースを駆動するアプリケーションのテストを簡単にできる多くの便利なツールを用意しています。その一つは指定した抽出条件に一致するデータがデータベース中に存在するかをアサートするseeInDatabase
ヘルパです。たとえばuser
テーブルの中にemail
フィールドがsally@example.com
の値のレコードが存在するかを確認したいとしましょう。次のようにテストできます。Laravel also provides a variety of helpful tools to make it easier to test your database driven applications. First, you may use the seeInDatabase
helper to assert that data exists in the database matching a given set of criteria. For example, if we would like to verify that there is a record in the users
table with the email
value of sally@example.com
, we can do the following:
public function testDatabase()
{
// アプリケーションを呼び出す…
$this->seeInDatabase('users', ['email' => 'sally@example.com']);
}
もちろん、seeInDatabase
メソッドやその他のヘルパは、利便性のために用意しています。PHPUnitの組み込みアサートメソッドを自分のテストに使用するのを制限するものではありません。Of course, the seeInDatabase
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
一つの選択肢はそれぞれのテストの後にデータベースをロールバックし、次のテストの前にマイグレーションする方法です。Laravelはこれを自動的に処理するために、シンプルなDatabaseMigrations
トレイトを用意しています。テストクラスでこのトレイトを使用するだけです。One option is to rollback the database after each test and migrate it before the next test. Laravel provides a simple DatabaseMigrations
trait that will automatically handle this for you. Simply use the trait on your test class:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
use DatabaseMigrations;
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->visit('/')
->see('Laravel 5');
}
}
トランザクションの使用Using Transactions
もう一つの選択肢は、各テストケースをデータベーストランザクションでラップしてしまうことです。Laravelはこれを自動的に行うために便利なDatabaseTransactions
トレイトを用意してます。Another option is to wrap every test case in a database transaction. Again, Laravel provides a convenient DatabaseTransactions
trait that will automatically handle this:
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
use DatabaseTransactions;
/**
* 基本的な機能テストの例
*
* @return void
*/
public function testBasicExample()
{
$this->visit('/')
->see('Laravel 5');
}
}
注意: このトレイトはデフォルトのデータベース接続をトランザクションでラップしているだけです。Note: This trait will only wrap the default database connection in a transaction.
モデルファクトリModel Factories
テスト実行前に何件かのレコードをデータベースに挿入する必要はよく起きます。こうしたテストデータを手動でそれぞれのカラムへ値を指定する代わりに、Laravelでは「ファクトリ」を使用しEloquentモデルの各属性にデフォルトを設定できます。手始めにアプリケーションのdatabase/factories/ModelFactory.php
ファイルを見てください。このファイルには最初からファクトリの定義が含まれています。When testing, it is common to 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 your Eloquent models[/docs/{{version}}/eloquent] using "factories". To get started, take a look at the database/factories/ModelFactory.php
file in your application. Out of the box, this file contains one factory definition:
$factory->define(App\User::class, function (Faker\Generator $faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
ファクトリで定義しているクロージャの中から、モデルの全属性に対するデフォルトのテスト値を返しています。このクロージャはFaker PHPライブラリーのインスタンスを受け取っており、これはテストのための多用なランダムデータを生成するのに便利です。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 the Faker[https://github.com/fzaninotto/Faker] PHP library, which allows you to conveniently generate various kinds of random data for testing.
もちろん追加のファクトリをModelFactory.php
に自由に追加できます。系統立てるためには各モデルのファクトリーファイルを追加したほうが良いでしょう。たとえば、database/factories
ディレクトリの中へUserFactory.php
とCommentFactory.php
ファイルを作成します。Of course, you are free to add your own additional factories to the ModelFactory.php
file. You may also create additional factory files for each model for better organization. For example, you could create UserFactory.php
and CommentFactory.php
files within your database/factories
directory.
複数のファクトリタイプMultiple Factory Types
時々、同じEloquentモデルクラスに対し、複数のファクトリを持ちたいことがあります。たとえば、たぶん通常のユーザに加えて「管理者(administrator)」のためのファクトリも用意したいでしょう。defineAs
メソッドを使用すれば、そうしたファクトリを定義できます。Sometimes you may wish to have multiple factories for the same Eloquent model class. For example, perhaps you would like to have a factory for "Administrator" users in addition to normal users. You may define these factories using the defineAs
method:
$factory->defineAs(App\User::class, 'admin', function ($faker) {
return [
'name' => $faker->name,
'email' => $faker->email,
'password' => str_random(10),
'remember_token' => str_random(10),
'admin' => true,
];
});
基本のユーザファクトリから全属性を複製する代わりに、属性を取得するraw
メソッドを使用できます。一度属性を取得したら、必要な追加の値を追加できます。Instead of duplicating all of the attributes from your base user factory, you may use the raw
method to retrieve the base attributes. Once you have the attributes, simply supplement them with any additional values you require:
$factory->defineAs(App\User::class, 'admin', function ($faker) use ($factory) {
$user = $factory->raw(App\User::class);
return array_merge($user, ['admin' => true]);
});
テスト中のファクトリ使用Using Factories In Tests
ファクトリを定義し終えたら、テストかデータベースのシーディング(初期値設定)ファイルの中で、グローバルなfactory
関数を使用してモデルインスタンスを生成できます。では、モデル生成の例をいくつか見てみましょう。最初はmake
メソッドでモデルを生成し、データベースには保存しないでみましょう。Once you have defined your factories, you may use them in your tests or database seed files to generate model instances using the global factory
function. So, let's take a look at a few examples of creating models. First, we'll use the make
method, which creates models but does not save them to the database:
public function testDatabase()
{
$user = factory(App\User::class)->make();
// モデルをテストで使用…
}
モデルのデフォルト値をオーバーライドしたい場合は、make
メソッドに配列で値を渡してください。指定した値のみ置き換わり、残りの値はファクトリで指定したデフォルト値のまま残ります。If you would like to override some of the default values of your models, you may pass an array of values to the make
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:
$user = factory(App\User::class)->make([
'name' => 'Abigail',
]);
さらにモデルのコレクションや指定したタイプのモデルも生成できます。You may also create a Collection of many models or create models of a given type:
// App\Userインスタンスを3つ生成
$users = factory(App\User::class, 3)->make();
// App\Userの"admin"インスタンスを生成
$user = factory(App\User::class, 'admin')->make();
// App\Userの"admin"インスタンスを3つ生成
$users = factory(App\User::class, 'admin', 3)->make();
保存するファクトリモデルPersisting Factory Models
create
メソッドはモデルインスタンスを生成するだけでなく、Eloquentのsave
メソッドを使用しデータベースへ保存します。The create
method not only creates the model instances, but also saves them to the database using Eloquent's save
method:
public function testDatabase()
{
$user = factory(App\User::class)->create();
// テスト中で生成したモデルを使用する…
}
ここでも、create
メソッドに配列で値を渡すことで、モデルの属性をオーバーライドできます。Again, you may override attributes on the model by passing an array to the create
method:
$user = factory(App\User::class)->create([
'name' => 'Abigail',
]);
モデルへのリレーション追加Adding Relations To Models
複数のモデルをデータベースへ保存することもできます。以下の例では、生成したモデルにリレーションを付けています。複数モデルの生成にcreate
メソッドを使用する場合、インスタンスのコレクションが返されます。そのため、コレクションで使用できるeach
などの便利な関数が利用できます。You may even persist multiple models to the database. In this example, we'll even attach a relation to the created models. When using the create
method to create multiple models, an Eloquent collection instance[/docs/{{version}}/eloquent-collections] is returned, allowing you to use any of the convenient functions provided by the collection, such as each
:
$users = factory(App\User::class, 3)
->create()
->each(function ($u) {
$u->posts()->save(factory(App\Post::class)->make());
});
リレーションと属性クロージャRelations & Attribute Closures
クロージャ属性をファクトリ定義の中で使い、モデルとのリレーションを追加することもできます。たとえば、Post
を作成する時に、新しいUser
インスタンスも作成したい場合は、以下のようになります。You may also attach relationships to models using Closure attributes in your factory definitions. For example, if you would like to create a new User
instance when creating a Post
, you may do the following:
$factory->define(App\Post::class, function ($faker) {
return [
'title' => $faker->title,
'content' => $faker->paragraph,
'user_id' => function () {
return factory(App\User::class)->create()->id;
}
];
});
さらに、クロージャは評価済みのファクトリーの配列を受け取ることもできます。These Closures also receive the evaluated attribute array of the factory that contains them:
$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;
}
];
});
モックMocking
イベントのモックMocking Events
Laravelのイベントシステムを多用している場合、テスト中は静かにしてもらうか、特定のイベントモックしたいと思うでしょう。たとえばユーザ登録のテスト中は、たぶんUserRegistered
イベントのハンドラには全部起動してもらいたくないでしょう。起動されたら"Welcome"メールを送り…などされるでしょう。If you are making heavy use of Laravel's event system, you may wish to silence or mock certain events while testing. For example, if you are testing user registration, you probably do not want all of a UserRegistered
event's handlers firing, since these may send "welcome" e-mails, etc.
Laravelはイベントハンドラを実行させずに期待するイベントが発行されたことを確認する、便利なexpectsEvents
メソッドを用意しています。Laravel provides a convenient expectsEvents
method that verifies the expected events are fired, but prevents any handlers for those events from running:
<?php
class ExampleTest extends TestCase
{
public function testUserRegistration()
{
$this->expectsEvents(App\Events\UserRegistered::class);
// ユーザー登録コードのテスト…
}
}
指定したイベントが発行されないことを確認するには、doesntExpectEvents
メソッドを使います。You may use the doesntExpectEvents
method to verify that the given events are not fired:
<?php
class ExampleTest extends TestCase
{
public function testPodcastPurchase()
{
$this->expectsEvents(App\Events\PodcastWasPurchased::class);
$this->doesntExpectEvents(App\Events\PaymentWasDeclined::class);
// ポッドキャスト購入コードのテスト…
}
}
全イベントハンドラの実行を停止したい場合は、withoutEvents
メソッドを使用してください。If you would like to prevent all event handlers from running, you may use the withoutEvents
method:
<?php
class ExampleTest extends TestCase
{
public function testUserRegistration()
{
$this->withoutEvents();
// ユーザー登録コードのテスト…
}
}
ジョブのモックMocking Jobs
場合によりアプリケーションへリクエストを作成し、コントローラーにより特定のジョブがディスパッチされることだけをテストしたい場合もあります。これにより、ジョブのロジックから切り離し、ルート/コントローラーを独立してテストできるようになります。もちろん、それからジョブ自身を別のテストクラスに分けてテストできます。Sometimes, you may wish to simply test that specific jobs are dispatched by your controllers when making requests to your application. This allows you to test your routes / controllers in isolation - set apart from your job's logic. Of course, you can then test the job itself in a separate test class.
Laravelは便利なexpectsJobs
メソッドを用意しており、期待しているジョブがディスパッチされたかを検査できます。しかしジョブ自身は実行されません。Laravel provides a convenient expectsJobs
method that will verify that the expected jobs are dispatched, but the job itself will not be executed:
<?php
class ExampleTest extends TestCase
{
public function testPurchasePodcast()
{
$this->expectsJobs(App\Jobs\PurchasePodcast::class);
// ポッドキャスト購入コードのテスト…
}
}
注意: このメソッドは
DispatchesJobs
トレイトのdispatch
メソッドか、dispatch
ヘルパ関数により起動されたジョブだけを検知します。直接Queue::push
で送られたジョブは検知できません。Note: This method only detects jobs that are dispatched via theDispatchesJobs
trait's dispatch methods or thedispatch
helper function. It does not detect jobs that are sent directly toQueue::push
.
ファサードのモックMocking Facades
テスト時、頻繁にLaravelのファサードの呼び出しをモックしたくなります。たとえば以下のようなコントローラーアクションを考えてください。When testing, you may often want to mock a call to a Laravel facade[/docs/{{version}}/facades]. For example, consider the following controller action:
<?php
namespace App\Http\Controllers;
use Cache;
class UserController extends Controller
{
/**
* アプリケーションの全ユーザーリストの表示
*
* @return Response
*/
public function index()
{
$value = Cache::get('key');
//
}
}
shouldReceive
メソッドを使用し、Cache
ファサードへの呼び出しをモックできます。これはMockeryのモックインスタンスを返します。ファサードはLaravelのサービスコンテナにより管理され、依存解決されていますので、典型的な静的クラスよりもかなり高いテスタビリティーを持っています。例としてCache
ファサードへの呼び出しをモックしてみましょう。We can mock the call to the Cache
facade by using the shouldReceive
method, which will return an instance of a Mockery[https://github.com/padraic/mockery] mock. Since facades are actually resolved and managed by the Laravel service container[/docs/{{version}}/container], they have much more testability than a typical static class. For example, let's mock our call to the Cache
facade:
<?php
class FooTest extends TestCase
{
public function testGetIndex()
{
Cache::shouldReceive('get')
->once()
->with('key')
->andReturn('value');
$this->visit('/users')->see('value');
}
}
注意:
Request
ファサードはモックしてはいけません。テスト実行時にcall
とpost
のようなHTTPヘルパメソッドへ望みの入力を渡してください。Note: You should not mock theRequest
facade. Instead, pass the input you desire into the HTTP helper methods such ascall
andpost
when running your test.