
この一連の記事では、以下の仕様に従ってローバーソフトウェアを構築します 。 これにより、次のアプローチを実践できます。
- モノリシックリポジトリ-MonoRepo (モノリシックリポジトリ)
- コマンド/クエリの責任分離-CQRS (読み取りと書き込みの責任分離)
- イベントソーシング-ES (ソースとしてのイベント)
- テスト駆動開発-TDD (テストによる開発)
前のパートでは、ナビゲーションパッケージを作成し 、その中に初めて使用するための入力パラメーターを検証するLandRover
クラスがあります。
ローバーは最初に所定の位置に着陸する必要があります。 位置は、座標( X
およびY
、整数)および方向(文字列値north
、 east
、 west
またはsouth
)で構成されます。
今日はLandRover
をリファクタリングしLandRover
:
cd packages/navigation git checkout 2-landing
責任
LandRover
見ると、変更の2つの理由がわかります。
x
座標とy
座標はfloat
値を取るか、追加のz
軸を持つことができます- 向きは角度で指定するか、垂直方向に設定できます。
これは、 LandRover
から抽出された2つの新しいクラス、 Coordinates
とOrientation
暗示しています。 この記事では、座標を管理します。
座標
まず、 phpspecを使用してテストクラスを作成しましょう 。
vendor/bin/phpspec describe 'MarsRover\Navigation\Coordinates'
新しいspec/MarsRover/Navigation/CoordinatesSpec.php
ファイルが表示されます:
namespace spec\MarsRover\Navigation; use MarsRover\Navigation\Coordinates; use PhpSpec\ObjectBehavior; use Prophecy\Argument; class CoordinatesSpec extends ObjectBehavior { function it_is_initializable() { $this->shouldHaveType(Coordinates::class); } }
LandRover
テストクラスの基礎を使用して編集します。
namespace spec\MarsRover\Navigation; use PhpSpec\ObjectBehavior; class CoordinatesSpec extends ObjectBehavior { const X = 23; const Y = 42; function it_has_x_coordinate() { $this->beConstructedWith( self::X, self::Y ); $this->getX()->shouldBe(self::X); } function it_cannot_have_non_integer_x_coordinate() { $this->beConstructedWith( 'Nobody expects the Spanish Inquisition!', self::Y ); $this->shouldThrow( \InvalidArgumentException::class )->duringInstantiation(); } function it_has_y_coordinate() { $this->beConstructedWith( self::X, self::Y ); $this->getY()->shouldBe(self::Y); } function it_cannot_have_non_integer_y_coordinate() { $this->beConstructedWith( self::X, 'No one expects the Spanish Inquisition!' ); $this->shouldThrow( \InvalidArgumentException::class )->duringInstantiation(); } }
ここでテストを実行すると、 CoordinatesSpec
クラスがロードされます。
vendor/bin/phpspec run
そして彼はsrc/MarsRover/Navigation/Coordinates.php
ファイルを作成します:
namespace MarsRover\Navigation; class Coordinates { private $argument1; private $argument2; public function __construct($argument1, $argument2) { $this->argument1 = $argument1; $this->argument2 = $argument2; } public function getX() { } public function getY() { } }
今では、 LandRover
クラスに対して既に行ったことを完了するだけです。
namespace MarsRover\Navigation; class Coordinates { private $x; private $y; public function __construct($x, $y) { if (false === is_int($x)) { throw new \InvalidArgumentException( 'X coordinate must be an integer' ); } $this->x = $x; if (false === is_int($y)) { throw new \InvalidArgumentException( 'Y coordinate must be an integer' ); } $this->y = $y; } public function getX() : int { return $this->x; } public function getY() : int { return $this->y; } }
テストを実行します。
vendor/bin/phpspec run
すべて緑! LandRover
テストクラスを更新して、新しい座標クラスを使用します。
namespace spec\MarsRover\Navigation; use PhpSpec\ObjectBehavior; class LandRoverSpec extends ObjectBehavior { const X = 23; const Y = 42; const ORIENTATION = 'north'; function it_has_coordinates() { $this->beConstructedWith( self::X, self::Y, self::ORIENTATION ); $coordinates = $this->getCoordinates(); $coordinates->getX()->shouldBe(self::X); $coordinates->getY()->shouldBe(self::Y); } function it_has_an_orientation() { $this->beConstructedWith( self::X, self::Y, self::ORIENTATION ); $this->getOrientation()->shouldBe(self::ORIENTATION); } function it_cannot_have_a_non_cardinal_orientation() { $this->beConstructedWith( self::X, self::Y, 'A hareng!' ); $this->shouldThrow( \InvalidArgumentException::class )->duringInstantiation(); } }
x
とy
値を検証する必要はなくなりました。これをすべてCoordinates
クラスに信頼し、これを処理してくれます。 これで、 LandRover
クラスを更新できます。
namespace MarsRover\Navigation; class LandRover { const VALID_ORIENTATIONS = ['north', 'east', 'west', 'south']; private $coordinates; private $orientation; public function __construct($x, $y, $orientation) { $this->coordinates = new Coordinates($x, $y); if (false === in_array($orientation, self::VALID_ORIENTATIONS, true)) { throw new \InvalidArgumentException( 'Orientation must be one of: ' .implode(', ', self::VALID_ORIENTATIONS) ); } $this->orientation = $orientation; } public function getCoordinates() : Coordinates { return $this->coordinates; } public function getOrientation() : string { return $this->orientation; } }
もう一度、テストを実行して、すべてが正常かどうかを確認します。
vendor/bin/phpspec run
素晴らしい、それはすべてなくなった! 変更を送信する:
git add -A git commit -m '2: Created Coordinates'
おわりに
テスト、コード、リファクタリングのTDDの全サイクルを実施しました。 phpspec
使用は、テストクラスのプロトタイピングに非常に役立ち、コード自体にも役立ちました。
次は何ですか
次の記事では、 Orientation
とLandRover
を分離しLandRover
。
前: ローバー、着陸