Home > OS >  Why in unit test object's field doesn't change in Django
Why in unit test object's field doesn't change in Django

Time:03-21

I don't understand why my test doesn't work. I have a page with product. There is a form with button 'Buy product'. After pushing this button, if a client have enough money, the item will bought and the ammount of money in the account will change. But in my test the ammount of money will be the same after buying a product, although the object(purchased item) will be created.

Purchased item model:

class BoughtItem(models.Model):
    name = models.CharField(max_length=100, verbose_name='Название товара или акции', blank=True)
    price = models.IntegerField(verbose_name='Цена', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

Profile model:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    money = models.IntegerField(default=0)

form:

class BuyForm(forms.ModelForm):

    class Meta:
        model = BoughtItem
        fields = ('name',)
        widgets = {'name': forms.HiddenInput()}

view:

class ItemDetailView(generic.DetailView):
    model = Item
    template_name = 'item_detail.html'
    context_object_name = 'item'

    def get_object(self, queryset=None):
        return get_object_or_404(Item, pk=self.kwargs.get('pk'))

    def post(self, request, *args, **kwargs):
        buy_form = BuyForm(request.POST)
        if buy_form.is_valid():
            purchase = buy_form.save(commit=False)
            item = self.get_object()
            user = Profile.objects.get(user__username=request.user.username)
            if user.money >= item.price:
                sum_difference = user.money - item.price
                user.money = sum_difference
                user.save()
                purchase.name = item.name
                purchase.price = item.price
                purchase.save()
                return HttpResponseRedirect(reverse('account', kwargs={'username': request.user.username}))
            else:
                return HttpResponseRedirect(reverse('purchase_error'))
        else:
            return render(request, 'item_detail.html',
                          context={'buy_form': buy_form, 'object': self.get_object()})

urls:

urlpatterns = [
    path('shop_list/', ShopListView.as_view(), name='shop_list'),
    path('<str:name>', ItemListView.as_view(), name='shop_detail'),
    path('item/<int:pk>', ItemDetailView.as_view(), name='item_detail'),
    path('purchase_error/', purchase_error, name='purchase_error'),
]

test:

class ShopTest(TestCase):
    @classmethod
    def setUpTestData(cls):
        Shop.objects.create(
            name='Samsung',
            description='Магазин электроники',
        )
        Item.objects.create(
            name='Телефон Samsung A50',
            description='Описание телефона',
            price=20000,
            shop_id=Shop.objects.get(name='Samsung').pk
        )

        user = User.objects.create(username='testuser')
        user.set_password('12345')
        user.save()

        Profile.objects.create(
            user=user,
            money=100000
        )

    def test_if_change_field_money_after_purchase(self):
        self.client.login(username='testuser', password='12345')
        user = Profile.objects.get(user__username='testuser')
        item = Item.objects.get(pk=1)
        self.client.post(reverse('item_detail', kwargs={'pk': item.pk}))
        self.assertNotEquals(user.money, 100000)

CodePudding user response:

The changes have been saved to the DB but your object still contains the old data, call instance.refresh_from_db() to get the latest data from the DB

def test_if_change_field_money_after_purchase(self):
    self.client.login(username='testuser', password='12345')
    user = Profile.objects.get(user__username='testuser')
    item = Item.objects.get(pk=1)

    user.refresh_from_db()

    self.assertNotEquals(user.money, 100000)
  • Related