Laravel 在建立時就有考慮到單元測試。事實上,它支持立即使用被引入的 PHPUnit 做測試,而且已經(jīng)為你的應(yīng)用程序建立了 phpunit.xml
文件。
在 tests
文件夾有提供一個測試例子。在安裝新 Laravel 應(yīng)用程序之后,只要在命令行上執(zhí)行 phpunit
來進行測試流程。
要建立一個測試案例,只要在 tests
文件夾建立新的測試文件。測試類必須繼承自 TestCase
,接著你可以如你平常使用 PHPUnit 一般去定義測試方法。
class FooTest extends TestCase { public function testSomethingIsTrue() { $this->assertTrue(true); }}
你可以從終端機執(zhí)行 phpunit
命令來執(zhí)行應(yīng)用程序的所有測試。
注意: 如果你定義自己的
setUp
方法, 請記得調(diào)用parent::setUp
。
當執(zhí)行單元測試的時候,Laravel 會自動將環(huán)境配置成 testing
。另外 Laravel 會在測試環(huán)境導(dǎo)入 session
和 cache
的配置文件。當在測試環(huán)境里這兩個驅(qū)動會被配置為 array
(空數(shù)組),代表在測試的時候沒有 session 或 cache 數(shù)據(jù)將會被保留。視情況你可以任意的建立你需要的測試環(huán)境配置。
testing
環(huán)境的變量可以在 phpunit.xml
文件中配置。
你可以使用 call
方法,輕易地調(diào)用你的任何一個路由來測試:
$response = $this->call('GET', 'user/profile');$response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content);
接著你可以檢查 Illuminate\Http\Response
對象:
$this->assertEquals('Hello World', $response->getContent());
你也可以從測試調(diào)用控制器:
$response = $this->action('GET', 'HomeController@index');$response = $this->action('GET', 'UserController@profile', ['user' => 1]);
注意: 當使用
action
方法的時候,你不需要指定完整的控制器命名空間。只需要指定App\Http\Controllers
命名空間后面的類名稱部分。
getContent
方法會返回求值后的字串內(nèi)容響應(yīng)。如果你的路由返回一個 View
,你可以通過 original
屬性訪問它:
$view = $response->original;$this->assertEquals('John', $view['name']);
你可以使用 callSecure
方法去調(diào)用 HTTPS 路由:
$response = $this->callSecure('GET', 'foo/bar');
當測試的時候,你或許常會想要模擬調(diào)用 Laravel 靜態(tài) facade。舉個例子,思考下面的控制器行為:
public function getIndex(){ Event::fire('foo', ['name' => 'Dayle']); return 'All done!';}
我們可以在 facade 上使用 shouldReceive
方法,來模擬調(diào)用 Event
類,它將會返回一個 Mockery mock 對象實例。
public function testGetIndex(){ Event::shouldReceive('fire')->once()->with('foo', ['name' => 'Dayle']); $this->call('GET', '/');}
注意: 你不應(yīng)該模擬
Request
facade。取而代之,當執(zhí)行你的測試,傳遞想要的輸入數(shù)據(jù)進去call
方法。
Laravel 附帶幾個 assert
方法,讓測試更簡單一點:
public function testMethod(){ $this->call('GET', '/'); $this->assertResponseOk();}
$this->assertResponseStatus(403);
$this->assertRedirectedTo('foo');$this->assertRedirectedToRoute('route.name');$this->assertRedirectedToAction('Controller@method');
public function testMethod(){ $this->call('GET', '/'); $this->assertViewHas('name'); $this->assertViewHas('age', $value);}
public function testMethod(){ $this->call('GET', '/'); $this->assertSessionHas('name'); $this->assertSessionHas('age', $value);}
public function testMethod(){ $this->call('GET', '/'); $this->assertSessionHasErrors(); // Asserting the session has errors for a given key... $this->assertSessionHasErrors('name'); // Asserting the session has errors for several keys... $this->assertSessionHasErrors(['name', 'age']);}
public function testMethod(){ $this->call('GET', '/'); $this->assertHasOldInput();}
TestCase
類包含幾個輔助方法讓應(yīng)用程序的測試更為簡單。
$this->session(['foo' => 'bar']);$this->flushSession();
你可以使用 be
方法配置目前為通過身份驗證的用戶:
$user = new User(['name' => 'John']);$this->be($user);
你可以從測試中使用 seed
方法重新填充你的數(shù)據(jù)庫:
$this->seed();$this->seed('DatabaseSeeder');
更多建立填充數(shù)據(jù)的信息可以在文檔的 遷移與數(shù)據(jù)填充 部分找到。
你可能已經(jīng)知道,你可以通過 $this->app
在任何測試方法中訪問你的(應(yīng)用程序服務(wù)容器)。這個服務(wù)容器會在每個測試類被重置。如果你希望在給定的方法手動強制重置應(yīng)用程序,你可以從你的測試方法使用 refreshApplication
方法。這將會重置任何額外的綁定,例如那些從測試案例執(zhí)行開始被放到 IoC 容器的 mocks。
更多建議: