5

私が経験しているLaravel 4の問題に関して、助けていただければ幸いです。

コントローラーのルート、特にアンケートへの回答のルーティングを担当するコントローラーをテストしています。ユーザーが質問をスキップしようとしたり、ユーザーが存在しない質問をリクエストしたりするなどのシナリオをテストしています。

これまでにすべてのシナリオで作成したテストは、PHPunit を使用して期待どおりに動作します。私が現在書いているテストには、いくつ$this->call()$this->client->request()の実行が含まれており、それが問題の原因です。$this->call()1 つのテスト メソッドで or を何度も (具体的には 2 回以上)実行する$this->client->request()と、ターミナルで ErrorException が発生します。

{"error":{"type":"ErrorException","message":"未定義の変数: header","file":"/Volumes/Dev HD/dmh/app/views/layouts/steps.php","ライン1}}

$this->call()またはテストメソッドの量を1つに減らすと、$this->client->request()うまくいき、例外は表示されません。私は次のコードを使用しています:

コード

/**
 * When the user skips questions they have not yet answered, the user 
 * should be redirected back to the first unanswered question.
 *
 * @return void
 */
public function testDiscoverSkipQuestions()
{
    // Get the first question.
    $domCrawler = $this->client->request('GET', 'style/discover');

    // Answer the first question
    $form = $domCrawler->selectButton("Next »")->form();
    $form['question_1'] = 'A:0';
    $response = $this->client->submit($form);
    $this->assertRedirectedTo('style/discover/2');

    // Get the 5th question.
    $this->call('GET', 'style/discover/5');
    // BROKEN

    // Expect to be redirected to the 2nd question.
    $this->assertRedirectedTo('style/discover/2');
    $this->assertSessionHas('attention');
}

何か案は?

複数の通話を発信するには、何かをリセットする必要がありますか? このような複数の呼び出しを行うことは悪い習慣ですか? このテストを書くためのより良い方法はありますか? どんなアイデアでも大歓迎です。

本当にありがとう!

4

1 に答える 1

14

考えられる解決策:

$this->client->restart()新しいリクエストを開始するために使用します。

説明/詳細:

よし、これがうさぎの穴だ :D

  1. LaravelTestCaseIlluminate\Foundation\Testing\TestCaseを拡張します
  2. Illuminate\Foundation\Testing\TestCaseIlluminate\Foundation\Testing\Clientを使用して偽のリクエストを作成します。
  3. Illuminate\Foundation\Testing\Client extends Symfony\Component\HttpKernel\Client
  4. Symfony\Component\HttpKernel\Clientは抽象クラスSymfony\Component\BrowserKit\ Client を拡張します
  5. 抽象クラスSymfony\Component\BrowserKit\ クライアントにはメソッドrestart()があります

したがって、私はあなたの場合を信じています(私はこれを個人的にテストしていません)、次のことができるはずです:

/**
 * When the user skips questions they have not yet answered, the user 
 * should be redirected back to the first unanswered question.
 *
 * @return void
 */
public function testDiscoverSkipQuestions()
{
    // Get the first question.
    $domCrawler = $this->client->request('GET', 'style/discover');

    // Answer the first question
    $form = $domCrawler->selectButton("Next »")->form();
    $form['question_1'] = 'A:0';
    $response = $this->client->submit($form);
    $this->assertRedirectedTo('style/discover/2');

    // ******** Restart for new request ********
    $this->client->restart();

    // Get the 5th question.
    $this->call('GET', 'style/discover/5');
    // ******** SHOULD NOW WORK - call() is a proxy to $this->client->request(); ********

    // Expect to be redirected to the 2nd question.
    $this->assertRedirectedTo('style/discover/2');
    $this->assertSessionHas('attention');
}

call() メソッドは、使用するためのプロキシであることに注意してください$this->client->request()

それが役立つことを願っています! コードの継承を掘り下げて、必要なことを行うための便利なメソッドが存在するかどうかを確認することを恐れないでください-変更は、多くの場合、既に存在しています:D

改善(?)

これらのテストは、「単体テスト」ではなく「統合テスト」に傾いている可能性があることに注意してください。統合テストは、継続的統合フレームワークで使用する場合により適している場合があります。詳細については、この質問を参照してください。

于 2013-07-07T20:43:36.740 に答える