I’m writing a new Django app with Django Rest Framework and trying to use TDD as much as I can but I’m a bit unsure as to where to draw the line between testing the serializer and testing the view.
Let me give you an example.
If I have the following serializer:-
class EventMembershipSerializer(serializers.ModelSerializer):
select = serializers.BooleanField(required=False)
class Meta:
fields = ['event']
def validate(self, attrs):
if not attrs["event"].started:
if "is_selected" in attrs:
raise serializers.ValidationError(
{"select": "Cannot set selected for event in the future."}
)
return super().validate(attrs)
and the following view:-
class EventMembershipViewSet(viewsets.GenericViewSet):
queryset = Event.objects.all()
serializer_class = EventSerializer
then I can write this to test the serializer:-
def test_create_select(
self,
past_event_factory,
):
event = past_event_factory()
data = {
"event": event.hashid,
"select": True
}
with pytest.raises(
ValidationError, match="Cannot set selected for event in the future."
):
serializer = EventMembershipSerializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
and this to test the view:-
def test_create(
self,
past_event_factory,
api_client
):
url = reverse(<url>)
event = past_event_factory()
data = {
"event": event.hashid,
"select": True,
}
response = api_client.post(url, data, format="json")
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.data["non_field_errors"][0] == "Cannot set selected for event in the future."
But this really feels like I’m testing the same thing twice to me. If I’m checking for the same error in both tests, that feels pointless. If the serializer test exists and is working then as long as the view uses that serializer with the same data, then it will definitely produce that error message under those conditions.
So should my view test just test that the view uses that serializer? Or is it OK to duplicate test data and results like this? Where should I draw the line?