引言
最近使用到laravel的consolo命令行工具,在編寫命令,想寫一些測試的時候,發現官方文檔中并沒有提到command的測試方法。花了點時間,翻墻找了資料,實踐成功并記錄一下,方便更多人。
推薦:《laravel教程》
測試方法
大家都知道laravel中使用了很多symfony的成熟組件,Laravel的console組件使用的就是Symfony/console。
幸運的是,Symfony/console 組件中提供了用于command測試的CommandTester, 使用方法如下
... use?FooCommand; use?SymfonyComponentConsoleApplication; use?SymfonyComponentConsoleTesterCommandTester; ... public?function?testSample(){ ????//創建一個console測試應用平臺,用來搭載測試的命令 ????$application?=?new?Application(); ???? ????//創建待測試的command ????$testedCommand?=?$this->app->make(FooCommand::class); ????//設置命令執行需要的laravel依賴 ????$testedCommand->setLaravel(app()); ????//添加待測試的command到測試應用上 ????//同時command?也綁定?application ????$application->add($testedCommand); ????//實例化命令測試類 ????$commandTester?=?new?CommandTester($testedCommand); ????//命令輸入流,對應每次交互需要提供的輸入內容 ????$commandTester->setInputs([ ????????//... ????????]); ????//執行命令 ????$commandTester->execute(['command'?=>?$testedCommand->getName()]); ????//對命令執行結果進行斷言測試,主要是依靠正則判斷 ????//$commandTester->getDisplay()?方法可以獲取命令執行后的輸出結果 ????$this->assertRegExp("/some?reg/",?$commandTester->getDisplay()); }
示例
我們現在有一個手動創建新用戶的命令createUser,作用就是手動創建一個用戶。
需要交互式讓用戶輸入name,email,password,comfirm password,這些數據。
待測試的command
<?php namespace AppConsoleCommands; use AppUser; use IlluminateAuthEventsRegistered; use IlluminateConsoleCommand; use IlluminateSupportFacadesValidator; class CreateUser extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'createUser'; /** * The console command description. * * @var string */ protected $description = 'create new user for system manually'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $this->line($this->description); ????????//?獲取輸入的數據 ????????$data?=?[ ????????????'name'?=>?$this->ask('What's?your?name?'), ????????????'email'?=>?$this->ask('What's?your?email?'), ????????????'password'?=>?$this->secret('What's?your?password?'), ????????????'password_confirmation'?=>?$this->secret('Pleas?confirm?your?password.') ????????]; ????????//?驗證輸入內容 ????????$validator?=?$this->makeValidator($data); ????????if?($validator->fails())?{ ????????????foreach?($validator->errors()->toArray()?as?$error)?{ ????????????????foreach?($error?as?$message)?{ ????????????????????$this->error($message); ????????????????} ????????????} ????????????return; ????????} ????????//?向用戶確認輸入信息 ????????if?(!$this->confirm('Confirm?your?info:?'?.?PHP_EOL?.?'name:'?.?$data['name']?.?PHP_EOL?.?'email:'?.?$data['email']?.?PHP_EOL?.?'is?this?correct?'))?{ ????????????return; ????????} ????????//?注冊 ????????$user?=?$this->create($data); ????????event(new?Registered($user)); ????????$this->line('User?'?.?$user->name?.?'?successfully?registered'); ????} ????/** ?????*?Get?a?validator?for?an?incoming?registration?request. ?????* ?????*?@param??array?$data ?????*?@return?IlluminateContractsValidationValidator ?????*/ ????protected?function?makeValidator($data) ????{ ????????return?Validator::make($data,?[ ????????????'name'?=>?'required|string|max:255|unique:users', ????????????'email'?=>?'required|string|email|max:255|unique:users', ????????????'password'?=>?'required|string|min:6|confirmed' ????????]); ????} ????/** ?????*?Create?a?new?user?instance?after?a?valid?registration. ?????* ?????*?@param??array?$data ?????*?@return?AppUser ?????*/ ????protected?function?create($data) ????{ ????????return?User::create([ ????????????'name'?=>?$data['name'], ????????????'email'?=>?$data['email'], ????????????'password'?=>?bcrypt($data['password']) ????????]); ????} }
正確的結果
如果正確輸入信息的話,會得到如下輸出
$?path-to-your-app/app#?php?artisan?createUser create?new?user?for?system?manually ?What's?your?name?: ?>?vestin ?What's?your?email?: ?>?correct@abc.com ?What's?your?password?: ?>? ?Pleas?confirm?your?password.: ?>? ?Confirm?your?info:? name:vestin email:correct@abc.com is?this?correct??(yes/no)?[no]: ?>?yes User?vestin?successfully?registered
想要測試的內容
我想要測試兩塊內容:
1.數據輸入驗證測試
● email有效性測試
●?password兩次輸入是否相同的測試
2.正確創建用戶測試
●?編寫單元測試
<?php namespace TestsUnitcommand; use AppConsoleCommandsCreateUser; use SymfonyComponentConsoleApplication; use SymfonyComponentConsoleTesterCommandTester; use TestsTestCase; use IlluminateFoundationTestingRefreshDatabase; class CreateUserTest extends TestCase { use RefreshDatabase; /** * 測試數據驗證 * * @return void */ public function testValidation() { $application = new Application(); $testedCommand = $this->app->make(CreateUser::class); ????????$testedCommand->setLaravel(app()); ????????$application->add($testedCommand); ????????$commandTester?=?new?CommandTester($testedCommand); ????????$commandTester->setInputs(['Vestin',?'badEmail@abc',?'123456',?'654321']); ????????$commandTester->execute(['command'?=>?$testedCommand->getName()]); ????????//?assert ????????$this->assertRegExp("/The?email?must?be?a?valid?email?address/",?$commandTester->getDisplay()); ????????$commandTester->setInputs(['vestin',?'correct@abc.com',?'123456',?'654321']); ????????$commandTester->execute(['command'?=>?$testedCommand->getName()]); ????????//?assert ????????$this->assertRegExp("/The?password?confirmation?does?not?match/",?$commandTester->getDisplay()); ????} ????/** ?????*?測試成功注冊用戶 ?????* ?????*?@return?void ?????*/ ????public?function?testSuccess() ????{ ????????$application?=?new?Application(); ????????$testedCommand?=?$this->app->make(CreateUser::class); ????????$testedCommand->setLaravel(app()); ????????$application->add($testedCommand); ????????$commandTester?=?new?CommandTester($testedCommand); ????????$commandTester->setInputs(['Vestin',?'correct@abc.com',?'123456',?'123456',?'y']); ????????$commandTester->execute(['command'?=>?$testedCommand->getName()]); ????????//?assert ????????$this->assertRegExp("/User?Vestin?successfully?registered/",?$commandTester->getDisplay()); ????????$this->assertDatabaseHas('users',?[ ????????????'email'?=>?'correct@abc.com', ????????????'name'?=>?'Vestin' ????????]); ????} }
執行測試
$?path-to-your-app/app#??./vendor/bin/phpunit? PHPUnit?6.4.3?by?Sebastian?Bergmann?and?contributors. ..??????????????????????????????????????????????????????????????????3?/?3?(100%) Time:?659?ms,?Memory:?14.00MB
? 版權聲明
文章版權歸作者所有,未經允許請勿轉載。
THE END
喜歡就支持一下吧
相關推薦