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
Mockeryを読んでみたよ
Search
chiroruxx
January 18, 2023
Technology
1
180
Mockeryを読んでみたよ
第148回 PHP勉強会@東京のLTで使用したスライドです。
chiroruxx
January 18, 2023
Tweet
Share
More Decks by chiroruxx
See All by chiroruxx
PHPはいつから死んでいるかの調査
chiroruxx
2
440
元phperから見たGoの良いところ
chiroruxx
0
21
Go Connectへの想い
chiroruxx
0
180
GraphQLに入門してみた
chiroruxx
2
210
ドキュメンテーションコメント再入門
chiroruxx
0
100
我流カンファレンス楽しみ術
chiroruxx
0
61
最初の一歩を踏み出す言葉
chiroruxx
4
1.1k
PhpStormをIDEとして使う
chiroruxx
0
64
Goを始めて感じたPHPの魅力
chiroruxx
1
68
Other Decks in Technology
See All in Technology
エンジニアゼロの組織から内製開発の DX をどう実現したのか / How did we achieve DX in in-house development in an organization with zero engineers?
genkiogasawara
7
3k
生成AI活用推進の為にやったこと/やらなかったこと
ktc_wada
0
140
使われないものを作るな!出口から作るデータ分析基盤 / Data Platform Development Starting from the User Needs
amaotone
16
4.6k
AWS アーキテクチャ作図入門/aws-architecture-diagram-101
ma2shita
16
6.7k
Taking Flight with Tailwind CSS
opdavies
0
4.3k
AI JIMY - 登壇(インストール編)
hanacchi
0
150
RubyKaigi 2024 - Make Your Own Regex Engine!
makenowjust
0
140
グイグイ系QAエンジニアでやっていくよ!
____rina____
0
760
生成AIと産業向けソフトウェアの自動生成 〜 ハノーバーメッセ2024より〜
kioto
2
420
cgroup v2 で何が変わったのか / TechFeed Experts Night #28
tenforward
2
160
Shinagile 2024
kawaguti
PRO
2
120
YJIT Makes Rails 1.7x faster / RubyKaigi 2024
k0kubun
3
450
Featured
See All Featured
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
20
1.8k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
126
32k
Typedesign – Prime Four
hannesfritz
36
2.1k
Faster Mobile Websites
deanohume
300
30k
In The Pink: A Labor of Love
frogandcode
138
21k
No one is an island. Learnings from fostering a developers community.
thoeni
16
2.1k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
9
1.3k
GraphQLとの向き合い方2022年版
quramy
33
13k
Web Components: a chance to create the future
zenorocha
306
41k
Bootstrapping a Software Product
garrettdimon
PRO
302
110k
From Idea to $5000 a Month in 5 Months
shpigford
377
45k
What's new in Ruby 2.0
geeforr
338
31k
Transcript
Mockeryを 読んでみたよ 2023/01/18 第148回 PHP勉強会@東京
コードリーディングの歴史 第146回PHP勉強会 ▪ 柚⼝ ましろう さん 第147回PHP勉強会 ▪ y_sone さん
流れにのっていくしかない!! 🌊
> whoami ▪ 名前: ちひろ/ちろ/前⽥ ▪ Twitter: @chiroruxxxx ▪ 所属:
東京都⽴産業技術⼤学院⼤学 産業技術専攻 情報アーキテクチャコース 追川PBL ▪ テーマ: スクラムの理論と実践
Mockery とは ▪ モック(テストダブル)を作ってくれるライブラリ ▪ ユニットテストとかで便利
サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator();
$this->assertSame( '** テスト太郎 **', $decorator->decorate($user) );
サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator();
$this->assertSame( '** テスト太郎 **', $decorator->decorate($user) ); モックしたクラスは Userクラス︖
サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator();
$this->assertSame( '** テスト太郎 **', $decorator->decorate($user) ); モックしたクラスは Userクラス︖ コンストラクタで 引数が必要だけど︖
サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator();
$this->assertSame( '** テスト太郎 **', $decorator->decorate($user) ); モックしたクラスは Userクラス︖ コンストラクタで 引数が必要だけど︖ こんなメソッド ないけど︖
いったい何者なんだ・・・!!
コードを読んで追っていくぞ 💪
今回の⽬的 ▪ Mockery::mock(User::class) で作成されるクラスが何者なのかを追ってく ▪ 今回紹介しない話も、ブログに書いています – あしたからがんばる - Mockeryでのモックの作り⽅を調べてみた
コードを読む ▪ PhpStorm + XDebug で1⾏ずつ状態を確認しながら読める ▪ 設定がちょっとだけ⾯倒 – PHPerKaigi
2023で・・・?
None
さっそく読んでいきます
クラス定義の読み込み ▪ ファイルを読み込んでる ▪ 展開してみると・・・? $code = file_get_contents(__DIR__ . '/../Mock.php');
クラス定義の読み込み $code = ' <?php class Mock implements MockInterface {
// ... public function shouldReceive(...$methodNames) { // ... ';
クラス定義の読み込み $code = ' <?php class Mock implements MockInterface {
// ... public function shouldReceive(...$methodNames) { // ... '; 💡 モックでメソッドが使える
クラスの継承 ▪ Userクラスを継承するように書き換えてる $code = str_replace( "implements MockInterface", "extends ¥¥"
. $className . " implements MockInterface", $code );
クラスの継承 $code = ' <?php class Mock extends ¥App¥Models¥User implements
MockInterface { // ... public function shouldReceive(...$methodNames) { // ... '; 💡 User 型として扱える
クラスのロード ▪ ええい! eval じゃい! ▪ ただの⽂字列から実⾏可能な状態に eval("?>" . $definition->getCode());
クラスのロード ▪ クラスはできた!!インスタンスはまだ作ってない <?php class Mock extends ¥App¥Models¥User implements MockInterface
{ // ... public function shouldReceive(...$methodNames) { // ...
インスタンスの作成 ▪ リフレクションクラスを使って 💡コンストラクタ実⾏無しでインスタンスを作 成 ▪ ・・・⿊魔術だ!! $reflectionClass = $this->getReflectionClass($className);
return $reflectionClass->newInstanceWithoutConstructor();
インスタンスの作成
まとめ ▪ モックしたクラスは User クラス? – User クラスを継承しているのでUser型として扱える ▪ shouldRecieve
なんてメソッドは User クラスにないけど? – User クラスを継承した先で定義しているので使える ▪ コンストラクタで引数が必要だけど? – リフレクションを使ってコンストラクタ無しで⽣成してる
まとめ ▪ みんなが使ってるあのライブラリも、蓋を開ければ案外ゴリ押し ▪ みんなも気軽にゴリ押しでライブラリを作ってみては?