Troubleshooting

DRF production에서 정상작동 하는데 test 통과 안되는 문제

Wibaek 2023. 9. 21. 11:58
728x90

문제 상황: DRF에서 nested 구조가 포함된 요소에 대해 POST 를 했을때 실 서비스에서는 정상적으로 생성되나, test에서는 nested 정보들이 반영이 안되는 오류

 

앞선 오류와 비슷한 느낌일거라는 생각이 들어 우선 validated_data등을 체크해보았다.

 

우선 테스트에서 serializer단의 validated_data와 view단의 request.data를 확인했다.

# Test request.data
<QueryDict:{
    "title": ["Post Restaurant Listing Test"],
    "is_private": ["True"],
    "restaurant_list": ["{'restaurant': {'uuid': UUID('d915e440-238c-45d7-bc95-5e1cc89c13af')}, 'order': 1}"],
}>

# Test validated_data
{"title": "Post Restaurant Listing Test", "is_private": True}

그리고 실제 production의 validated_data, request.data를 확인했다.

# Production request.data
{
    "title": "Post Restaurant Listing Test",
    "is_private": True,
    "restaurant_list": [{"restaurant": {"uuid": "d1f1b6a5-5aaa-4a1e-9cb4-1236dd36bd82"}, "order": 1}],
}

# Production validated_data
{
    "title": "Post Restaurant Listing Test",
    "is_private": True,
    "restaurant_list": [
        OrderedDict([("restaurant", OrderedDict([("uuid", UUID("d1f1b6a5-5aaa-4a1e-9cb4-1236dd36bd82"))])), ("order", 1)])
    ],
}

 

확인하면 test에서 보낸값으로는 제대로 validated 처리가 되지 않았다. 그 이유는 production에서는 제대로 json이 디코딩되었는데, test에서는 restaurant_list 내부의 값은 json decoding이 되지 않은걸로 보인다. 또한 다른값들도 리스트 안에 들어있는등 문제가 있어 보인다.

 

해결 방법:

# 기존
restaurant_listing_data = {
    "title": "Post Restaurant Listing Test",
    "is_private": True,
    "restaurant_list": [
        {
            "restaurant": {
                "uuid": self.restaurant.uuid,
            },
            "order": 1,
        }
    ],
}
response = self.client.post(reverse("restaurant_listing_list"), data=restaurant_listing_data)

# 수정
restaurant_listing_data = {
    "title": "Post Restaurant Listing Test",
    "is_private": True,
    "restaurant_list": [
        {
            "restaurant": {
                "uuid": self.restaurant.uuid,
            },
            "order": 1,
        }
    ],
}
restaurant_listing_data_json = json.dumps(restaurant_listing_data)
response = self.client.post(
    reverse("restaurant_listing_list"), data=restaurant_listing_data_json, content_type="application/json"
)

수동으로 json dumps를 해주고, application/json type으로 전송해주었다.

728x90