Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
継続的にLaravelのUnitTestを書く上で 気をつけていること
Search
stwile
September 28, 2021
Technology
250
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
継続的にLaravelのUnitTestを書く上で 気をつけていること
stwile
September 28, 2021
More Decks by stwile
See All by stwile
Fat Controller は悪か? ~光のFat Controller・闇のガリController~
stwile
2
1.9k
フレームワークが生み出す負債や複雑さに対して、PHPUnitと付き合っていく
stwile
1
2.8k
TDD視点から見る、Laravel・Requestクラスの依存性
stwile
0
150
Other Decks in Technology
See All in Technology
Guerilla InnerSource in enterprises, during the AI hype
onenashev
PRO
0
150
多摩川(.dev)ランニング入門 / Tamagawa.dev#3
fujiwara3
3
390
Beyond the Hype: Practical AI for Your Oracle Database with MCP
thatjeffsmith
1
280
作り直せるコードは迅速に 作り直せないDBは慎重に - AI時代のプロダクトエンジニアが「判断の不可逆性」で開発速度を変える話
kinosuke01
0
270
AIで仕事のやり方を変える
matsu7874
1
950
少人数データチームのDevin活用実践事例
runandy16
2
450
多層防御と最⼩権限で実現する、安全なAIエージェント設計パターン
lycorptech_jp
PRO
0
210
生成AIのテナント制御とシャドーMCP対策 | AIを"止めずに"、情報を守る
yukun
0
120
AI時代のAPI品質を支えるガードレール / API Guardrails for API quality in the AI era
yokawasa
1
150
生成AI時代の クレデンシャルとパーミッション設計
nrinetcom
PRO
4
1.6k
AI時代に、プロダクトの数だけ積み上がる所有コストをどうエンジニアリングするか / Engineering the Cost of Ownership
kzkmaeda
1
1k
薬剤師(ドメインエキスパート)と一緒に育てる薬局向けAIアシスタント
kakehashi
PRO
2
120
Featured
See All Featured
Side Projects
sachag
455
43k
Optimising Largest Contentful Paint
csswizardry
37
3.9k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
490
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
650
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Docker and Python
trallard
47
4.2k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
490
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
128
56k
Unsuck your backbone
ammeep
672
58k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
310
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
SERP Conf. Vienna - Web Accessibility: Optimizing for Inclusivity and SEO
sarafernandez
2
1.6k
Transcript
継続的にLaravelのUnitTestを書く上で 気をつけていること 2021 年 9 月 28 日 ( 火
)
自己紹介 hyroky.(@handm871) 専門領域: 趣味: バックエンド🍓 ユニットテスト・設計 筋トレ🦾
テストとPHP周りについて • テスト駆動開発歴:5年 • PHP歴:5年 • Laravel歴:3年
テストコードについて思うこと • サンプルコードが圧倒的に少ない • プロダクトコードの設計は たくさん ある ◦ テストコードの設計は あんまり
ない
伝えたい人 テスト駆動開発に • 興味がある人 • 初心者
今日話すこと UnitTest について 依存注入できる形で実装する
サンプルコード class FetchTodoService { public function exec(string $user_id, int $todo_id):
array { $todo_repos = new TodoRepository(); $result = $todo_repos->fetchTodo($todo_id, $user_id); if ($result === []) { throw new NotFoundException('Todoのデータが存在しません'); } return $result; } }
何がまずいのか? • TodoRepositoryに依存している ◦ メソッド内で `new` している ◦ 代替できないことが問題 ◦
DBにテストデータを作る必要がある
Feature Test • [GET]: /api/todo • 実データを用いて機能の振る舞いを検証
Unit Test • TodoListController ◦ TodoFetchService ▪ TodoRepository
Unit Test TodoListController Jsonを返す FetchTodoService DBから受け取った値を検証する TodoRepository DBへ接続・SQLを実行
Unit Test TodoListController Jsonを返す FetchTodoService DBから受け取った値を検証する TodoRepository DBへ接続・SQLを実行 FetchTodoService はDB接続の責務は不要
変更前 class FetchTodoService { public function exec(string $user_id, int $todo_id):
array { $todo_repos = new TodoRepository(); $result = $todo_repos->fetchTodo($todo_id, $user_id); if ($result === []) { throw new NotFoundException('Todoのデータが存在しません'); } return $result; } }
変更後 class FetchTodoService { public function exec( string $user_id, int
$todo_id, TodoRepository $todo_repos, ): array { $result = $todo_repos->fetchTodo($todo_id, $user_id); if ($result === []) { throw new LogicException('Todoのデータが存在しません'); } return $result; } } TodoRepository を外部から注入
テストのサンプル class FetchTodoServiceTest extends TestCase { /** @test */ public
function データが存在しない場合、空の配列を返すべき (): void { $user_id = 'user_id'; $todo_id = 999999; $todo_repos_mock = Mockery::mock(TodoRepository ::class); $todo_repos_mock ->shouldReceive ('fetchTodo') ->once() ->with($user_id, $todo_id) ->andReturn([]); $service = new TodoService(); parent::expectedException (LogicException ::class); parent::expectExceptionMessage ('Todoのデータが存在しません '); $service->exec($user_id, $todo_id, $todo_repos_mock ); } } 引数を設定 返り値を設定
何がまずいのか? • TodoRepositoryに依存している ◦ メソッド内で `new` している ◦ 代替できないことが問題 ◦
DBにテストデータを作る必要がある
テスト駆動開発から見えるもの • テストを書くことが大変...とおもったら ◦ 設計を見直すいい機会
おわり