Reputation: 77
I'm making a marketplace app with Django REST framework which I'm new to.
I wrote a test to test the unique together field. It works as I wanted it to, raising a UNIQUE constraint failed error when the fields author and target are not unique together, but my question is how should I handle this error so that my test would pass.
models.py
class Review(models.Model):
FEEDBACK_CHOICES = [
('POSITIVE', 'positive'),
('NEUTRAL', 'neutral'),
('NEGATIVE', 'negative')
]
feedback = models.CharField(
max_length=8,
choices=FEEDBACK_CHOICES,
default='NEGATIVE'
)
review = models.TextField(max_length=200)
target = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='reviews',
on_delete=models.CASCADE
)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
related_name='given_reviews',
on_delete=models.CASCADE
)
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['created']
unique_together = ['author', 'target']
serializers.py
class ReviewSerializer(serializers.ModelSerializer):
target = serializers.PrimaryKeyRelatedField(
queryset=User.objects.all()
)
author = serializers.ReadOnlyField(source='author.id')
class Meta:
model = Review
fields = [
'id',
'feedback',
'review',
'target',
'author',
'created'
]
views.py
class ReviewViewSet(viewsets.ModelViewSet):
queryset = Review.objects.all()
serializer_class = ReviewSerializer
permission_classes = [
ReviewPermissions
]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
Upvotes: 0
Views: 1700
Reputation:
This is described in the documentation:
If only the expected_exception and expected_message parameters are given, returns a context manager so that the code being tested can be written inline rather than as a function:
with self.assertRaisesMessage(ValueError, 'invalid literal for int()'):
int('a')
But that is meant for tests on the model level.
If you use DRF's test client you should check for a response status other then 200 and override the exception handler in handle_exception
or related methods of ApiView, so that you can determine the cause and provide data in the response that makes it testable. You then inspect the response of the client, in the same way as you would with Django's Test Client.
You can for example return a json response like this:
{
success: false,
code: INTEGRITY_UNIQUE_ERROR,
message: this could contain details you could test for, like field names
}
Upvotes: 1