所有していないものを濡らさないでください

翻訳者:ルール自体はかなり古く、記事に示されている例は、私の意見では最も単純です。したがって、この記事は初心者に適しています。自動テストの作成に優れた経験を持つ人は、自分にとって新しいものを見つけることができない場合があります。UPD。著者が自分のレイヤーで作業しているフレームワークのすべてのAPIをラップすることを提案しているとはまだ思いませんが(まあ、それは非常に奇妙です)、むしろそれは大まかに構造化/型付けされた汎用クラスに関するものです、記事の例のHttpRequestのように。





Webアプリケーションは、多くの場合、HTTP要求を処理するように設計されています。オブジェクトは通常、リクエストデータをカプセル化するために使用されます。フレームワークによっては、次のようなインターフェースがある場合があります





interface HttpRequest
{
    public function get(string $name): string;

    // ...
}
      
      



またはのような特定のクラスでさえ





class HttpRequest
{
    public function get(string $name): string
    {
        // ...
    }

    // ...
}
      
      



これを使用してリクエストデータにアクセスできます(使用する必要があります)。





たとえば、SymfonyにはSymfony \ Component \ HttpFoundation \ Request :: get()があります。例として、処理しているHTTPリクエストのタイプ(GET、POST、またはその他)について心配する必要はありません。代わりに、HttpRequest :: get()のような暗黙のAPIとそれらがもたらす問題に焦点を当てましょう。





, , , get() , . . get():





class SomeController
{
    public function execute(HttpRequest $request): HttpResponse
    {
        $id     = $request->get('id');
        $amount = $request->get('amount');
        $price  = $request->get('price');

        // ...
    }
}
      
      



, action- (: (eng )). , HTTP-.





HttpRequest (stub) mock- SomeController , get() , : 'id', 'amount' 'price'.





, , action- .





SomeController HttpRequest (stub) unit PHPUnit :





$request = $this->createStub(HttpRequest::class);

$request->method('get')
        ->willReturnOnConsecutiveCalls(
              '1',
              '2',
              '3',
          );

$controller = new SomeController;

$controller->execute($request);
      
      



SomeController HttpRequest, mock-, :





$request = $this->createMock(HttpRequest::class);

$request->expects($this->exactly(3))
        ->method('get')
        ->withConsecutive(
            ['id'],
            ['amount'],
            ['price']
        )
        ->willReturnOnConsecutiveCalls(
            '1',
            '2',
            '3',
        );

$controller = new SomeController;

$controller->execute($request);
      
      



, , , ( . ).





, HttpRequest::get() : «id», «amount» , , «price».





SomeController::execute(), HttpRequest::get(), . , . .





, HTTP-, API, , HTTP, get(). , , , : HttpRequest , .





« , » « , ». 2009 « - »:





« , , , , , . , , , , , ».





, , ? :





« [...] , , - , , . [...], - API [...] "





:





interface SomeRequestInterface
{
    public function getId(): string;

    public function getAmount(): string;

    public function getPrice(): string;
}
      
      



, , value-. .





SomeRequestInterface :





$request = $this->createStub(SomeRequestInterface::class);

$request->method('getId')
        ->willReturn(1);

$request->method('getAmount')
        ->willReturn(2);

$request->method('getPrice')
        ->willReturn(3);
      
      



, HTTP- , - HTTP- . . HTTP- . . :





class SomeRequest implements SomeRequestInterface
{
    private HttpRequest $request;

    public function __construct(HttpRequest $request)
    {
        $this->request = $request;
    }

    public function getId(): string
    {
        return $this->request->get('id');
    }

    public function getAmount(): string
    {
        return $this->request->get('amount');
    }

    public function getPrice(): string
    {
        return $this->request->get('price');
    }
}
      
      



:





class SomeController
{
    public function execute(HttpRequest $request)
    {
        return $this->executable->execute(
            new SomeRequest($request)
        )
    }
}
      
      



SomeController , , HTTP .





もちろん、リクエストラッパーを各コントローラーに固有にする必要があります。コードに特定のヘッダーが必要ですか?それらを取得するためのメソッドを作成します。コードにアップロードされたファイルが必要ですか?これを正確に取得するメソッドを作成します。





完全なHTTPリクエストには、ヘッダー、値、アップロードされたファイル、POST本文などを含めることができます。インターフェースを所有していないときにこれらすべてのテストスタブまたはモックを設定すると、作業を完了できなくなります。独自のインターフェースを定義すると、タスクが大幅に簡素化されます。








All Articles