diadia

興味があることをやってみる。自分のメモを残しておきます。

Django Test retrofitが送信するデータを再現する

内容

django単体テストを実装する際にAndroid端末が送信するデータ形式を再現できなければ、単体テストの効果が得られない。 したがって最初にretrofitのpostメソッドの形式を確認し、それをそれぞれどのようにdjango(python)で再現すればよいかをメモしておく。

  1. retrofit POSTメソッド3パターン
  2. djangoで再現する

1. retrofit POSTメソッド3パターン

retrofitがPOSTメソッドで送信するパターンは3種類ある。

  • FORM ENCODED形式
  • REQUEST BODY形式
  • MULTIPART形式
//FORM ENCODED形式
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
//REQUEST BODY形式
@POST("users/new")
Call<User> createUser(@Body User user);
//MULTIPART形式
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

retrofit公式サイトより

2. djangoで再現する

前提としてretrofit POSTメソッド3パターンの例に対応する形式で記述する。
またリクエストの送信形式について調べられていないので、また分かったら理論的な側面も追記したいと思う。

FORM ENCODED形式のデータ

form形式にはinputのnameとそれに対応するvalueで送信されることから、 djangoで当該データを再現する場合にはdict形式で作成すればよい。 つまり以下を実行すれば良い。 

POST_USER_URL ="/user/edit"
data = {"first_name": "yasuo", "last_name": "nakanishi"}
client.post(POST_USER_URL, data)

また、データとしてdict型で送信するものの、valuejson形式で送信すると受け入れる場合がある。例えば以下のような感じ。

POST_ITEM_URL ="/hoge/hoge/"
data = { "user":json.dumps({"username":"test_user"},ensure_ascii=False)}
client.post(POST_ITEM_URL, data)

REQUEST BODY形式のデータを作成する

REQUEST BODY形式のデータ送信の場合は、最初にdictデータを作成する。次にそれをjson.dumps()でstr型に変換する。 またPOSTメソッド実行時にjson形式で送る旨を設定するcontent_type="application/json"を追加すれば良い。
ちなみにjson.dumpsを実行するときに、日本語が入っている等でdumpsした結果のデータが文字化けするケースに遭遇したなら、 ensure_ascii=Falseを追加しておけば文字化けは解消される。

#REQUEST BODY形式に対応したサンプル
URL = "/users/new"
data = {"user": {"username":"yasu", "email":"yasu@gmail.com", "gender":1 } }
client = APIClient()
#client.credentials(HTTP_AUTHORIZATION='Token ' + user_key)
response = client.post(
                URL, 
                json.dumps(data, ensure_ascii=False), 
                content_type="application/json"
                )

MULTIPART形式のデータ