0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SymfonyでXMLHttpRequestなAPIをテストする方法

Posted at

はじめに

Symfony2でテストを書いたことを前提に話を進めます。

XMLHttpRequestなリクエストって

ブラウザからAjaxで呼ばれるAPIを作ったときに、Controllerのテスト書くと思います。
その際、$request->isXmlHttpRequest()かどうかチェックしているとすると、テスト的にも、それを区別する必要があります。

XMLHttpRequestかどうかは、リクエストヘッダのX-Requested-WithXMLHttpRequestかどうかによって判断しているようです。

Symfony/Component/HttpFoundation/Request.php
public function isXmlHttpRequest()
{
    return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
}

request関数の引数に$headersが見当たらない?

下記のようなテストコードだったとして、$client->requestでリクエストヘッダが指定できれば、解決しそうです。

<?php
namespace App\Test\Controller;

use Symfony\Component\HttpKernel\Client;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
// Silexの場合は、use Silex\WebTestCase;

class ApiControllerTest extends WebTestCase
{
    /**
     * @test
     */
    public function apiAction()
    {
        $client = self::createClient();
        /** @var Client $client */
        
        $client->request('GET', '/path/to/api');

        $this->assertTrue($client->getResponse()->isOk());
        $this->assertJson($client->getResponse()->getContent());
    }

が、しかし、HTTPクライアントのrequest関数の引数に$headersが見当たらないのです。

Symfony/Component/BrowserKit/Client.php
/**
 * Calls a URI.
 *
 * @param string $method        The request method
 * @param string $uri           The URI to fetch
 * @param array  $parameters    The Request parameters
 * @param array  $files         The files
 * @param array  $server        The server parameters (HTTP headers are referenced with a HTTP_ prefix as PHP does)
 * @param string $content       The raw body data
 * @param bool   $changeHistory Whether to update the history or not (only used internally for back(), forward(), and reload())
 *
 * @return Crawler
 *
 * @api
 */
public function request($method, $uri, array $parameters = array(), array $files = array(), array $server = array(), $content = null, $changeHistory = true)

ググると、下記のissueが見つかり、ますます不安になります。
[BrowserKit]Cannot set Custom Header · Issue #5074 · symfony/symfony

結論、サーバー変数'HTTP_X_REQUESTED_WITH'に'XMLHttpRequest'をセットする

ここで慌てずに、request関数のコメントをよく見ると、

@param array  $server        The server parameters (HTTP headers are referenced with a HTTP_ prefix as PHP does)

とありますので、試しにサーバー変数'HTTP_X_REQUESTED_WITH'に'XMLHttpRequest'を指定すると、期待どおり動作します。

        $client->request('GET', $apiUrl, [], [],
            ['HTTP_X_REQUESTED_WITH' => 'XMLHttpRequest']);

        $this->assertTrue($client->getResponse()->isOk());
        $this->assertJson($client->getResponse()->getContent());
    }

おわりに

毎回、サーバー変数セットするのもあれなんで、Clientクラスを拡張して、ajaxRequest関数を作ってもいいかもしれません。
参考になりましたら、幸いです。

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?