1

私は現在、Djangoのアプリ(+ RESTフレームワーク)のためのいくつかのテストを足すと、データベースにテストデータをロードするいくつかの問題を抱えているをロードする前に。ジャンゴテスト - データベースにデータをロードするアプリケーション

私はいくつかの(非常に単純化された)コードを説明しましょう:

私のようなものであるDjangoのビューがありますので、基本的に私がする必要がある

view.py

from myapp.models import Item 
from myapp.utils import MyClass 

# need to initialize with the set of items 
item_set = {item.name for item in Item.objects.all()} 
my_class_object = MyClass(item_set) 

class MyView(APIView): 
    def post(selfself, request): 
     result = my_class_object.process(request.data) 
     return Response(result) 

をデータベースからのデータでクラスを初期化してから、このクラスをビューで使用して、エンドポイントが受け取ったデータを処理します。

今テスト:テストを実行する場合

from rest_framework.test import APILiveServerTestCase 
from myapp.models import Item 

class MyTest(APILiveServerTestCase): 

    def setUp(self): 
     self.URL = '/some_url_linking_to_myview/' 

     # load some data 
     Item.objects.create(name="first item") 
     Item.objects.create(name="second item") 

    def test_myview_return_correct_result(self): 
     post_data = {"foo"} 
     response = self.client.post(self.URL, 
            data=post_data, 
            format='json') 
     self.assertEqual(response.status_code, 200) 
     self.assertEqual(response.data, {"my_expected_result"}) 

my_test.pyは、何が起こるかは、現在のsetUp()メソッドを取得する前view.pyがロードされていることですこれらの2つの行でクラスをインスタンス化すると、次のようになります。

item_set = {item.name for item in Item.objects.all()} 
my_class_object = MyClass(item_set) 

データベースはまだ空です。

view.pyが実行される前にデータベースにデータを取得する方法があるか、またはsetUp()の後にアプリを強制的にリロードしたり、クラスを他の場所にインスタンス化したりする方法があるかどうかは疑問ですデータをロードした後に呼び出されますか?

ありがとうございました!

+1

これは、モジュールレベルでのDB-アクセスコードを置くべきではない理由の良いデモです。 –

答えて

0

開始コードを関数に入れて、投稿内から呼び出してみませんか?

class MyView(APIView): 
    def initialize(self): 
     item_set = {item.name for item in Item.objects.all()} 
     my_class_object = MyClass(item_set) 

    def post(self, request): 
     self.initialize() 
     result = my_class_object.process(request.data) 
     return Response(result) 

Edit 1 オプションで、データベース内のMyClassオブジェクトをロードするための固定具を使用することができ、あらかじめ

class MyTest(APILiveServerTestCase): 
    fixtures = [ 
     // my class objects fixtures file 
    ] 
    def setUp(): 
     // rest of the code 
+0

それは動作しますが、各呼び出しのクラスをインスタンス化するので(クラスのインスタンスを作成してクラスをインスタンス化するのは非常に高価な操作です)、それは遅すぎるでしょう。おそらくこれをいくつかのキャッシング戦略と組み合わせることもできます。 – Duf59

+0

コードがテストのためだけのものであれば、setUpでそのコードをインスタンス化できます。 しかし、プロダクションでは、クラスをグローバルにインスタンス化することは良い練習ではありません –

+0

あなたの入力をありがとう、私はフィクスチャを使ってみましたが、同じ問題がありました:データベースはクラスをインスタンス化した後にのみ設定されます。ブール値属性を使って最初のアプローチを試して、ビューの最初の呼び出し時にのみクラスをインスタンス化できるようにします。しかし、まだdjangoでそのようなことを処理するための '適切な'方法を探して:) – Duf59

0

私はあなたがsetUpTestData()を探していると思います。ここで

私は大量のデータを使用するつもりならば、私はこれを設定する方法おおよそ次のとおりです。

tests.py

from django.test import TestCase 
from .tests.test_data import base_data 

class MyClassTest(TestCase): 

    @classmethod 
    def setUpTestData(cls): 
     base_data.base_data(cls) 

base_data.py

from .models import MyClass 

def base_data(cls): 
    cls.MyClass1 = MyClass.objects.create(
     name="first_name" 
    ) 
    cls.MyClass2 = MyClass.objects.create(
     name="second_name" 
    ) 

もちろん、setUpTestData()関数ですべてを直接行うことができますあなたのテストデータを一番上に置いてください。

+0

あなたの答えのためのアダムありがとう。残念ながら、setUpTestDataを使用してもここでは役に立ちません(データベースはまだクラスをインスタンス化した後にデータが格納されます)。ですから、私の問題は基本的に、モジュールがコンパイルされたときにデータベースにアクセスしていることです。すべてがテストデータベースがセットアップされる前に発生します。 – Duf59

関連する問題