Slide 1

Slide 1 text

Mockeryを 読んでみたよ 2023/01/18 第148回 PHP勉強会@東京

Slide 2

Slide 2 text

コードリーディングの歴史 第146回PHP勉強会 ■ 柚⼝ ましろう さん 第147回PHP勉強会 ■ y_sone さん

Slide 3

Slide 3 text

流れにのっていくしかない!! 🌊

Slide 4

Slide 4 text

> whoami ■ 名前: ちひろ/ちろ/前⽥ ■ Twitter: @chiroruxxxx ■ 所属: 東京都⽴産業技術⼤学院⼤学 産業技術専攻 情報アーキテクチャコース 追川PBL ■ テーマ: スクラムの理論と実践

Slide 5

Slide 5 text

Mockery とは ■ モック(テストダブル)を作ってくれるライブラリ ■ ユニットテストとかで便利

Slide 6

Slide 6 text

サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator(); $this->assertSame( '** テスト太郎 **', $decorator->decorate($user) );

Slide 7

Slide 7 text

サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator(); $this->assertSame( '** テスト太郎 **', $decorator->decorate($user) ); モックしたクラスは Userクラス︖

Slide 8

Slide 8 text

サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator(); $this->assertSame( '** テスト太郎 **', $decorator->decorate($user) ); モックしたクラスは Userクラス︖ コンストラクタで 引数が必要だけど︖

Slide 9

Slide 9 text

サンプルコード $user = Mockery::mock(User::class); $user->shouldReceive('getFullName') ->andReturn('テスト太郎'); $decorator = new Decorator(); $this->assertSame( '** テスト太郎 **', $decorator->decorate($user) ); モックしたクラスは Userクラス︖ コンストラクタで 引数が必要だけど︖ こんなメソッド ないけど︖

Slide 10

Slide 10 text

いったい何者なんだ・・・!!

Slide 11

Slide 11 text

コードを読んで追っていくぞ 💪

Slide 12

Slide 12 text

今回の⽬的 ■ Mockery::mock(User::class) で作成されるクラスが何者なのかを追ってく ■ 今回紹介しない話も、ブログに書いています – あしたからがんばる - Mockeryでのモックの作り⽅を調べてみた

Slide 13

Slide 13 text

コードを読む ■ PhpStorm + XDebug で1⾏ずつ状態を確認しながら読める ■ 設定がちょっとだけ⾯倒 – PHPerKaigi 2023で・・・?

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

さっそく読んでいきます

Slide 16

Slide 16 text

クラス定義の読み込み ■ ファイルを読み込んでる ■ 展開してみると・・・? $code = file_get_contents(__DIR__ . '/../Mock.php');

Slide 17

Slide 17 text

クラス定義の読み込み $code = '

Slide 18

Slide 18 text

クラス定義の読み込み $code = '

Slide 19

Slide 19 text

クラスの継承 ■ Userクラスを継承するように書き換えてる $code = str_replace( "implements MockInterface", "extends ¥¥" . $className . " implements MockInterface", $code );

Slide 20

Slide 20 text

クラスの継承 $code = '

Slide 21

Slide 21 text

クラスのロード ■ ええい! eval じゃい! ■ ただの⽂字列から実⾏可能な状態に eval("?>" . $definition->getCode());

Slide 22

Slide 22 text

クラスのロード ■ クラスはできた!!インスタンスはまだ作ってない

Slide 23

Slide 23 text

インスタンスの作成 ■ リフレクションクラスを使って 💡コンストラクタ実⾏無しでインスタンスを作 成 ■ ・・・⿊魔術だ!! $reflectionClass = $this->getReflectionClass($className); return $reflectionClass->newInstanceWithoutConstructor();

Slide 24

Slide 24 text

インスタンスの作成

Slide 25

Slide 25 text

まとめ ■ モックしたクラスは User クラス? – User クラスを継承しているのでUser型として扱える ■ shouldRecieve なんてメソッドは User クラスにないけど? – User クラスを継承した先で定義しているので使える ■ コンストラクタで引数が必要だけど? – リフレクションを使ってコンストラクタ無しで⽣成してる

Slide 26

Slide 26 text

まとめ ■ みんなが使ってるあのライブラリも、蓋を開ければ案外ゴリ押し ■ みんなも気軽にゴリ押しでライブラリを作ってみては?