web-dev-qa-db-ja.com

DRFテスト:JSONの代わりにOrderedDictが返されます

Django Rest Frameworkのテストを実装しようとしています。ほとんどのテストに合格し、セットアップはスムーズに進みましたが、assertEqualで問題が発生しています。 JSONをOrderedDictと比較し続けるため、成功することはありません。

DRF shouldはJSONのみを返すので(右?)、OrderedDictがどこから来たのかわかりません。

テスト環境が比較前にJSONを解析している可能性はありますか?それは最悪だ。

特定のリソースへのGETリクエストの応答でデータのみをテストする統合テストを実行しています。これは、JSONフィクスチャに基づいて実行します。 RESTフレームワークの特定のコンポーネントをテストしていません。これは、コンポーネントの実装が非常に単純であり、DRFプロジェクトのテストですでにテストされているためです。

とにかく、誰かが私を助けてくれることを願っています!

20
ZvL

説明したように ここ 、これはテスト中のリクエストのデフォルトフォーマットがmultipartではなくjsonであるためです。次のようにAPI呼び出しに提供することで、形式を指定できます。

response = self.client.get('/something/1', format='json')

または、次のようにsettings.pyでデフォルトのテストリクエスト形式を設定できます。

REST_FRAMEWORK = {
    'TEST_REQUEST_DEFAULT_FORMAT': 'json',  # Use application/json instead of multipart/form-data requests in tests.
}

すべてのテストで自動的に修正します。

9
Allard Stijnman

テストが次のようになっている場合:

_class SomeTests(APITestCase):
    def test_something(self):
        response = self.client.get('/something/1')
        # assertions with response
_

その場合、応答は確かにJSONドキュメントではなくOrderedDictになります。幸いなことにDjango 1.9はresponse.json()メソッドを導入しました( https://docs.djangoproject.com/en/1.9/topics/testing/tools/#Django .test.Response.json )なので、応答をJSONに簡単に変換できます。pythonのjsonライブラリを使用することもできることに注意してください。

ここでの落とし穴は、Djangoのテストクライアント(DRFが拡張する)が「ダミーブラウザ」であるということです( https://docs.djangoproject.com/en/1.9/topics/testing/tools/#the-test-client )であり、Seleniumなどのブラウザ内フレームワークとまったく同じようには機能しません。したがって、HTTP呼び出しは、実際には、ロジックのテストに焦点を合わせ、ルーティング/ビュー/シリアライザーなどを修正するシミュレートされたHTTP呼び出しです。使用されています。

4
elnygren

Response.content(生のjson文字列を提供する)の代わりにresponse.data(解析されたjsonオブジェクトを返す)を使用しているようです。

http://www.Django-rest-framework.org/api-guide/testing/#testing-responses を参照してください

3
Norgg

SerializerMethodField を使用して問題を解決しました。

単純に、シリアライザークラス内で次の最後の3行をコピーし、resultを問題の原因となるjsonメンバーに置き換えます

class ConfigSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Config
        fields = ('id', 'url', 'email', "result",)

    # COPY NEXT 3 LINES AND CHANGE 'result' WITH THE JSON MEMBER THAT CAUSE THE PROBLEM
    result = serializers.SerializerMethodField()
    def get_result(self, obj):
        return obj.result

resultが次のように表示される前:

{result: "OrderedDict([('key1', 1), ('key2', OrderedDict([('key3', [1, 2, 3])]))])"}

解決後、resultは次のようになります。

{"result": {"key1":1,"key2":{"key3":[1,2,3]}}}
0

データをjson形式にダンプできます-

import json

httpResponse(json.dumps(data))を返します

0
Ashok Joshi