Tony Ayoub
Tony Ayoub

Reputation: 25

Django rest framework test does not create instances in test database

I'm having an issue in DRF tests when creating instance of a model, the status code in response is 'HTTP_201_CREATED' but the instance it self does not exist in the testing db.
here is my model :

class Item(SafeDeleteModel):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_("Owner"))
    name = models.CharField(_("Name"), max_length=150)
    category = TreeForeignKey('merssis.ItemCategory', on_delete=models.SET_NULL, null=True, verbose_name=_("Category"))
    fixed_price = models.FloatField(_("Fixed price"), default=0)
    main_pic = ProcessedImageField(verbose_name=_("Main picture"), upload_to='item_pics', processors=[ItemWatermarker()],format='JPEG')
    main_pic_thumbnail = ImageSpecField(source='main_pic',
        processors=[ResizeToFill(384, 256)],
        format='JPEG',
        options={'quality': 100})
    geo_location = models.PointField(srid=4326, null=True, blank=True, verbose_name=_("Geolocation"))
    _safedelete_policy = SOFT_DELETE_CASCADE

    def __str__(self):
        return self.name

Serializer :

class ItemCreateSerializer(GeoFeatureModelSerializer):
    PRICE_TYPE_CHOICES = (
        ('fixed', _('Fixed') ),
        ('open', _('Open') ),
    )
    owner = serializers.HiddenField(default=serializers.CurrentUserDefault())
    price_type = serializers.ChoiceField(choices=PRICE_TYPE_CHOICES)
    category = serializers.PrimaryKeyRelatedField(queryset=ItemCategory.objects.all(), many=False)#ItemCategorySerializer(many=False)
    main_pic = serializers.ImageField(use_url='item_pics')
   
    def validate(self, data):
        user = self.context['request'].user
        geo_data = data.get('geo_location')
        
        #Validate fixed price value
        if data['price_type'] == 'fixed':
            if data.get('fixed_price') == None or int(data.get('fixed_price')) <= 0:
                raise serializers.ValidationError({"fixed_price" :INVALIDE_PRICE_ERROR})
        
        #Price type is open should explicitly set fixed price to 0
        if data['price_type'] == 'open':
            data['fixed_price'] = 0

        #Validate geo_location
        #geo_location post data form ====> {"type":"Point", "coordinates":[37.0625,-95.677068]}
        if geo_data:
            if not validate_in_country_location(user, geo_data):
                raise serializers.ValidationError({"geo_location":OUTSIDE_COUNTRY_MSG})
        return data

    def create(self, validated_data):
        #Remove price_type value since it is not a field in the model
        #We used to determine th price type on the serializer only
        validated_data.pop('price_type')
        return Item(**validated_data)

    class Meta:
        model = Item
        geo_field = 'geo_location'
        fields =  ( 'owner',
                    'name', 
                    'price_type',
                    'category',
                    'fixed_price',
                    'main_pic',
                    'geo_location',
                    )

The view :

class ItemCreateAPIView(CreateAPIView):
    queryset = Item.objects.all()
    serializer_class = ItemCreateSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def perform_create(self, serializer, *args, **kwargs):
        self.check_object_permissions(self.request, self.request.user)
        serializer.save()

The test case :

class ItemTestCase(APITestCase):

    def test_create_new_item(self):
        """
        Testing Add new item functionality
        """

        self.client_1 = APIClient()
        self.user_1 = create_new_user(email='[email protected]', username='tester_1', password='qsdf654654', gender='male')
        self.client_1.login(username='tester_1',password='qsdf654654')

        image_file = create_test_image()

        category = ItemCategory.objects.create(name='SomeCat')
        new_item_data = {
        'name': 'New Item',
        'price_type' : 'open',
        'category': str(category.pk),
        'main_pic': image_file,
        }
        response = self.client_1.post(url, new_item_data, format='multipart')
        items = Item.objects.filter(name='New Item')
        print(response.status_code)
        self.assertEqual( response.status_code, status.HTTP_201_CREATED)
        self.assertEqual( items.count(), 1)

and when i run the test i get '201' printed in console AND AssertionError: 0 != 1
i'm fvkin confused

Upvotes: 1

Views: 293

Answers (1)

Brian Destura
Brian Destura

Reputation: 12068

In the serializer create() the object was never saved so change:

return Item(**validated_data)

to:

return Item.objects.create(**validated_data) # create the object

Upvotes: 1

Related Questions