Upgrade to Pro — share decks privately, control downloads, hide ads and more …

モックの泥沼から脱却するために、あえてDBにつないでテストしている話

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

 モックの泥沼から脱却するために、あえてDBにつないでテストしている話

PHPerKaigi2021

Avatar for Kazuhei Arai

Kazuhei Arai

March 27, 2021
Tweet

More Decks by Kazuhei Arai

Other Decks in Programming

Transcript

  1. ς Ϋ ϊ ϩ δ ʔ ͷ ྗ Ͱ M

    & A ʹ ྲྀ ௨ ֵ ໋ Λ
  2. ϞοΫ͠ͳ͍Ϣχοτςετ class CommonTime { 
 public function __construct(int $timestamp) {

    $this->timestamp = $timestamp; } 
 public static function fromString($string) { return new static(strtotime($string)); } 
 public function getHour(): string { return date('H', $this->timestamp); }
  3. ϞοΫ͠ͳ͍Ϣχοτςετ public function testGetHour() { $time = CommonTime::fromString('2017-01-01 10:21:00'); $this->assertEquals('10',

    $time->getHour()); } จࣈྻ͔Β$PNNPO5JNFΫϥεΛ࡞ͬͯɺHFU)PVS͕࣌ؒ Λฦ͢͜ͱΛςετ
  4. ϞοΫΛ࢖ͬͨϢχοτςετ class MessageDomainService { 
 public function notifyMessage(MessageId $messageId): void

    { $message = $this->messageRepository->get($messageId); if ($message->needsNotification()) { $this->notificationRepository->add($message->notification()); } } ϝοηʔδΛऔಘͯ͠ɺඞཁͳΒ௨஌΋௥Ճ͢Δͱ͍͏Α͏ ͳॲཧ
  5. ϞοΫΛ࢖ͬͨϢχοτςετ public function testNotifyMessage() { $needsNotifyMessage = new Message(...); $this->mock(MessageRepository::class,

    function ($mock) use ($needsNotifyMessage) { $mock->shouldReceive('get') ->andReturn($needsNotifyMessage); }); $this->mock(NotificationRepository::class, function ($mock) use ($needsNotifyMessage) { $mock->shouldReceive('add') ->with($needsNotifyMessage->notification()); }); $domainService = app()->make(MessageDomainService::class); $domainService->notifyMessage($needsNotifyMessage->id()); } ҰͭҰͭͷσʔλΞΫηε෦෼ΛϞοΫʹͯ͠ɺؔ਺͕ݺ͹ Ε͍ͯΔ͔Ͳ͏͔Λ֬ೝ͍ͯ͘͠ɻ
  6. ϞοΫΛ࢖ͬͨϢχοτςετ public function testNotifyMessage() { $needsNotifyMessage = new Message(...); $this->mock(MessageRepository::class,

    function ($mock) use ($needsNotifyMessage) { $mock->shouldReceive('get') ->andReturn($needsNotifyMessage); }); $this->mock(NotificationRepository::class, function ($mock) use ($needsNotifyMessage) { $mock->shouldReceive('add') ->with($needsNotifyMessage->notification()); }); $domainService = app()->make(MessageDomainService::class); $domainService->notifyMessage($needsNotifyMessage->id()); } σʔλϕʔε͔Βऔಘͨ͠σʔλΛ࢖ͬͯɺෳ਺ͷςʔϒϧʹॻ͖ ࠐΈΛ͍ͯ͘͠Α͏ͳ৔߹ɺͨ͘͞ΜͷσʔλϕʔεΞΫηεΛ ϞοΫ͢Δඞཁ͕͋Δɻ
  7. ͋͑ͯɺ%#ʹͭͳ͙ public function testNotifyMessage() { $needsNotifyMessage = new Message(...); $domainService

    = app()->make(MessageDomainService::class); $domainService->notifyMessage($needsNotifyMessage->id());
 
 $notification = $this->notificationRepository->first(); $this->assertEquals($needsNotifyMessage->notification(), $notification) } ࣮ࡍͷ%#ʹॻ͖ࠐΜͰɺͦΕΛऔΓग़ͯ͠Ұக͍ͯ͠ Δ͔֬ೝ͢Δ͚ͩɻͱͯ΋γϯϓϧ
  8. ςετޙͷ෭࡞༻ΛͲ͏΍ͬͯରॲ͢Δ͔ αϯϓϧίʔυ͸-BSBWFMΛ࢖ͬͨ΋ͷɻTFUVQ ࣌ʹ USBOTBDUJPOΛுΓɺUFBS%PXO ࣌ʹSPMMCBDL͍ͯ͠Δ <?php declare(strict_types=1); namespace Tests; use

    Illuminate\Foundation\Testing\DatabaseTransactions; abstract class BaseDbIntegrationTest extends TestCase { use DatabaseTransactions; }
  9. ࣮ߦ࣌ؒΛͲ͏͢Δ͔ 1)16OJUͷઃఆͰςετΛ෼ׂ͠ɺ࣮ߦλΠϛϯάΛௐ੔͢ Δ͜ͱͰରॲ <testsuites> <testsuite name="Feature"> <directory suffix="Test.php">./tests/Feature</directory> </testsuite> <testsuite

    name="DbIntegration"> <directory suffix="Test.php">./tests/DbIntegration</directory> </testsuite> <testsuite name="Unit"> <directory suffix="Test.php">./tests/Unit</directory> </testsuite> </testsuites>