はじめに
こんばんは。 またまたcakephp3記事です。
もう cakephpも ver4.2.4とかなのですが、現場ではまだcakephp3を使用しているため致し方なし。という感じです。
今回は cakephpのevent機能を使用している際のテストコードです。
前回 eventの使用方法などは書いたのですが、使用している箇所のテストコードを今回書いたので、備忘録として残しておきます。
本題
前回使用した ExampleControllerのテストコードを書きます。
今回はわかりやすく UserContollerにして、actionも registerにします。
使用されているeventは NotificationEventListener
です。
今回は少しだけ具体的に NotificationEventListener
の処理を書きます。
ExampleController
<?php namespace App\Controller; use App\Repository\UserRepository; use App\EventListener\NotificationEventListener; use App\EventDispatcher; use Kojirock5260\Component\Adapter\SlackAdapter; use Kojirock5260\User\UseCase\RegisterUser; use Kojirock5260\User\Exception\RegisterUserException; class UserController extends AppController { public function registerAction() { try { $slackConfig = Configure::read('Slack'); $this->getEventManager()->on(new NotificationEventListener(new SlackAdapter($slackConfig))); $userId = (new RegisterUser( new UserRepository($this->UsersTable), new EventDispatcher($this->getEventManager()) ))($this->request->getData('userData')); $this->Flash->error('新規登録ありがとうございます。'); } catch (RegisterUserException $e) { $this->Flash->error('ユーザー登録が失敗しました。'); } } }
NotificationEventListener
<?php namespace App\EventListener; use Cake\Event\EventListenerInterface; class NotificationEventListener implements EventListenerInterface { private $slackAdapter; public function __construct(SlackAdapter $slackAdapter) { $this->slackAdapter = $slackAdapter; } public function implementedEvents(): array { return [ 'Notification.Slack' => 'notificationSlack', ]; } public function notificationSlack($event, array $data): void { $this->slackAdapter->send('ユーザー新規登録!', $data['params']); } }
本来はもっと複雑な処理があると思いますが、一旦はこんな感じにします。
この ExampleControllerをテストしたい場合、slackに通知するeventをmockしたくなります。
その場合は、以下のように書きます。
ExampleControllerTest.php
<?php namespace App\Test\TestCase\Controller; use Cake\Event\Event; use Cake\Event\EventManager; use Cake\TestSuite\IntegrationTestCase; class UserControllerTest extends IntegrationTestCase { /** * @test */ public function register() { EventManager::instance()->on('Notification.Slack', function (Event $event) { $slackAdapterMock = $this->createPartialMock(SlackAdapter::class, ['send']); $slackAdapterMock->method('send')->willReturn(true); $event->getSubject()->slackAdapter = $slackAdapterMock; }); $this->enableCsrfToken(); $this->post('/user/register', [ 'email' => 'hogehoge@fuga.com', 'name' => 'kojirock' ]); $flashData = $this->_requestSession->read('Flash.flash.0'); self::assertSame('Flash/success', $flashData['element']); } }
これで、slackAdapterのsend()メソッドを実行せずそれ以外のコードが実行されるようになります。
終わりに
cakephp4にあげて、早くDIの恩恵を受けたいです。。 このテストコード関連でも、やっぱり外から注入できないとmockがとてもつらいことになってしまってて、大変です。
現場からは以上です。