Djangoテストでtest.Response.requestを駆使せよ!詳細解説とサンプルコード集


test.Response.request は、Django のテストフレームワーク django.test で提供されるオブジェクトであり、テスト対象のビューからのレスポンスに関連する情報を提供します。これは、テスト対象のビューが期待通りのリクエストを処理し、適切なレスポンスを返していることを検証する際に役立ちます。

属性とメソッド

test.Response.request は、以下の属性とメソッドを持ちます。

属性

  • cookies: リクエストクッキー
  • headers: リクエストヘッダー
  • data: リクエストボディ (POST や PUT などの場合)
  • path: リクエストパス
  • method: リクエストメソッド (GET、POST、PUT など)

メソッド

  • is_secure(): リクエストが HTTPS 経由かどうかを判定
  • is_ajax(): リクエストが AJAX リクエストかどうかを判定

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        response = self.client.get('/my-view/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.request.method, 'GET')
        self.assertEqual(response.request.path, '/my-view/')

上記の例では、MyViewTest クラスの test_my_view メソッドで test.Response.request オブジェクトを使用して、ビューからのレスポンスを検証しています。

  • テスト対象のビューがミドルウェアを使用している場合、test.Response.request オブジェクトにミドルウェアによって変更された情報が含まれる可能性があります。
  • test.Response.request オブジェクトは、テスト対象のビューが実際に処理したリクエストの情報に基づいて作成されます。


例 1: リクエストメソッドとパスの検証

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        response = self.client.get('/my-view/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.request.method, 'GET')
        self.assertEqual(response.request.path, '/my-view/')

この例では、MyViewTest クラスの test_my_view メソッドで test.Response.request.methodtest.Response.request.path 属性を使用して、ビューからのレスポンスが GET リクエストであることと、パスが /my-view/ であることを検証しています。

例 2: リクエストボディの検証

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        data = {'name': 'John Doe', 'email': '[email protected]'}
        response = self.client.post('/my-view/', data=data)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.request.data, data)

この例では、MyViewTest クラスの test_my_view メソッドで test.Response.request.data 属性を使用して、ビューからのレスポンスのボディが期待通りのデータであることを検証しています。

例 3: リクエストヘッダーの検証

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        headers = {'Authorization': 'Bearer my-token'}
        response = self.client.get('/my-view/', headers=headers)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.request.headers, headers)

この例では、MyViewTest クラスの test_my_view メソッドで test.Response.request.headers 属性を使用して、ビューからのレスポンスのヘッダーが期待通りのヘッダーであることを検証しています。

例 4: リクエストクッキーの検証

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        cookies = {'sessionid': 'my-session-id'}
        response = self.client.get('/my-view/', cookies=cookies)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.request.cookies, cookies)

例 5: AJAX リクエストの判定

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        headers = {'X-Requested-With': 'XMLHttpRequest'}
        response = self.client.get('/my-view/', headers=headers)
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.request.is_ajax())

この例では、MyViewTest クラスの test_my_view メソッドで test.Response.request.is_ajax() メソッドを使用して、ビューからのレスポンスが AJAX リクエストであることを判定しています。

例 6: HTTPS リクエストの判定

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        response = self.client.get('https://my-view/')
        self.assertEqual(response.status_code, 200)
        self.assertTrue(response.request.is_secure())

この例では、MyViewTest クラスの test_my_view メソッドで test.Response.request.is_secure() メソッドを使用して、ビューからのレスポンスが HTTPS 経由のリクエストであることを判定しています。



代替方法

以下の代替方法を検討することができます。

self.request 属性

self.request 属性は、テスト対象のビュー関数内で使用できる属性であり、現在のリクエストに関する情報を提供します。test.Response.request オブジェクトと同様に、メソッドと属性を持ちますが、テスト対象のビュー関数内でのみ使用できます。

from django.test import TestCase

class MyViewTest(TestCase):
    def test_my_view(self):
        response = self.client.get('/my-view/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(self.request.method, 'GET')
        self.assertEqual(self.request.path, '/my-view/')

request モジュール

request モジュールは、Django のコアモジュールであり、現在のリクエストに関する情報を提供します。test.Response.request オブジェクトと同様に、メソッドと属性を持ちますが、テスト対象のビュー関数内だけでなく、テストコードのどこでも使用できます。

from django.test import TestCase
from django.http import HttpRequest

class MyViewTest(TestCase):
    def test_my_view(self):
        request = HttpRequest()
        request.method = 'GET'
        request.path = '/my-view/'
        response = self.client.get('/my-view/')
        self.assertEqual(response.status_code, 200)
        self.assertEqual(request.method, 'GET')
        self.assertEqual(request.path, '/my-view/')

カスタムテストヘルパー

独自のテストヘルパーを作成して、テスト対象のビューからのレスポンスに関する情報を取得することができます。

from django.test import TestCase

class MyViewTest(TestCase):
    def get_request_info(self, response):
        request_method = response.request.method
        request_path = response.request.path
        return request_method, request_path

    def test_my_view(self):
        response = self.client.get('/my-view/')
        self.assertEqual(response.status_code, 200)
        request_method, request_path = self.get_request_info(response)
        self.assertEqual(request_method, 'GET')
        self.assertEqual(request_path, '/my-view/')

テスト対象のビューのソースコード

テスト対象のビューのソースコードを確認することで、ビューがどのようにリクエストを処理しているかを理解することができます。

選択の指針

どの代替方法を選択するかは、テスト対象の状況によって異なります。

  • テスト対象のビューの内部動作を理解したい場合
    テスト対象のビューのソースコードを確認するのが最も良いでしょう。
  • 再利用性を重視する場合
    カスタムテストヘルパーを作成するのが最も再利用性が高いです。
  • 柔軟性を重視する場合
    request モジュールを使用するのが最も柔軟です。
  • シンプルさを重視する場合
    self.request 属性を使用するのが最も簡単です。