API 부분의 리팩토링이 어느 정도 끝난 후 test code를 작성했다.
1. Category & Product
먼저 category와 product의 detail과 list를 get에 관련한 테스트 코드를 작성했다.
# category
class CategoryTestCase(APITestCase):
def setUp(self):
self.category = Category.objects.create(
category_name = 'test category',
main_description = 'test main description',
sub_description = 'test sub description'
)
def test_category_list_get(self):
response = self.client.get(reverse('category-list'))
self.assertEqual(response.status_code, 200)
def test_category_detail_get(self):
response = self.client.get(reverse('category-detail', args=(self.category.id, )))
self.assertEqual(response.status_code, 200)
# product
class ProductTestCase(APITestCase):
def setUp(self):
self.category = Category.objects.create(
category_name = 'test category',
main_description = 'test main description',
sub_description = 'test sub description'
)
self.feeling = Feeling.objects.create(name='test feeling')
self.skin_type = SkinType.objects.create(name='test skin type')
self.ingredient = Ingredient.objects.create(name='test ingredient')
self.product = Product.objects.create(
name = 'test name',
price = 1000.00,
size = 'test size',
description = 'test description',
category = self.category,
howtouse = {'test':'test'},
badge = 'test badge'
)
def test_product_list_get(self):
response = self.client.get(reverse('product-list'))
self.assertEqual(response.status_code, 200)
def test_product_detail_get(self):
response = self.client.get(reverse('product-detail', args=(self.product.id, )))
self.assertEqual(response.status_code, 200)
detail get의 경우, url에서 <int:pk> 부분이 있어 id를 넘기는 부분이 필요했고, 때문에 reverse 안에 args를 설정했다. 여기서 id를 가져오기 위해서 setUp 부분에서 object를 한 개씩 만들어 주었다.
2. Review
Review의 경우, view에서 permission_classes = [IsAuthenticated]로 설정되어 있는 경우가 많아 이 부분을 해결하는데 오랜 시간이 걸렸다.
내가 계속 마주한 에러로,
django.db.utils.IntegrityError: (1452, 'Cannot add or update a child row: a foreign key constraint fails ….
위와 같은 에러가 있었는데, 알고 보니 내가 model에서 기존에 만들어 둔 User에서 drf에서 제공하는 auth.model의 User로 바꾸고 makemigrations을 하지 않아서 발생한 에러였다. migrate까지 진행하지 잘 해결되었다.
또한 알게 된 점이 있다면, foreign key로 물려있는 부분은 ‘category=self.category’와 같이, 위에서 만든 객체를 가지고 와야 했지만 many to many field로 엮여 있는 부분은 객체를 생성한 하면 되고 product create 안에서 위에서 만든 객체를 가지고 올 필요가 없었다.
class ReviewTestCase(APITestCase):
def setUp(self):
self.user = User.objects.create_user(username='example', password='Password123!')
refresh = RefreshToken.for_user(self.user)
self.client.credentials(HTTP_AUTHORIZATION='Bearer {0}'.format(refresh.access_token))
self.category = Category.objects.create(
category_name = 'test category',
main_description = 'test main description',
sub_description = 'test sub description'
)
self.feeling = Feeling.objects.create(name='test feeling')
self.skin_type = SkinType.objects.create(name='test skin type')
self.ingredient = Ingredient.objects.create(name='test ingredient')
self.product = Product.objects.create(
name = 'test name',
price = 1000.00,
size = 'test size',
description = 'test description',
category = self.category,
howtouse = {'test':'test'},
badge = 'test badge'
)
self.review = Review.objects.create(
user = self.user,
product = self.product,
content = 'test content'
)
def test_reveiw_list_get(self):
response = self.client.get(reverse('review-list', args=(self.product.id, )))
self.assertEqual(response.status_code, 200)
def test_review_detail_get(self):
response = self.client.get(reverse('review-detail', args=(self.review.id, )))
self.assertEqual(response.status_code, 200)
review create에 관한 test의 경우, 이미 첫 번째 user는 리뷰를 작성한 것처럼 되어 있기 때문에 user를 하나 더 생성해서 진행했다. 그렇지 않고 첫 번째 user를 그대로 사용하면, “your review for this product already exists”라고 하는 error가 발생한다.
class ReviewTestCase(APITestCase):
def setUp(self):
self.user = User.objects.create_user(username='example', password='Password123!')
refresh = RefreshToken.for_user(self.user)
self.client.credentials(HTTP_AUTHORIZATION='Bearer {0}'.format(refresh.access_token))
self.user_two = User.objects.create_user(username='example2', password='Password123!')
refresh_two = RefreshToken.for_user(self.user_two)
self.client.credentials(HTTP_AUTHORIZATION='Bearer {0}'.format(refresh_two.access_token))
....
def test_review_create(self):
data = {
"user" : self.user_two,
"product": self.product,
"content": "test content"
}
response = self.client.post(reverse('review-create', args=(self.product.id, )), data)
self.assertEqual(response.status_code, 201)
'Django' 카테고리의 다른 글
[Django] DRF - 1차 프로젝트 리팩토링 (4) API Testing 2 (2) | 2022.06.15 |
---|---|
[Django] DRF - 1차 프로젝트 리팩토링 (3) Cart (0) | 2022.06.09 |
[Django] DRF - 1차 프로젝트 리팩토링 (2) Category detail & list GET (0) | 2022.06.07 |
[Django] DRF - 1차 프로젝트 리팩토링 (1) Product detail & list GET (0) | 2022.06.07 |
[Django] DRF - API Testing (0) | 2022.06.01 |