Home > Enterprise >  How to get User instance in Django tests.py?
How to get User instance in Django tests.py?

Time:07-06

I'm a beginner in Django, I created a simple ecommerce app and I'm writing some tests in tests.py. I'm trying to write a test which check the correct creation of an OrderItem, but I don't know how to obtain an user instance. Should I check the logged in user or the existence of the user is enough?

This is my store/models.py:

from tkinter import CASCADE
from django.db import models
from django.conf import settings

class Item(models.Model):
    name = models.CharField(max_length=50)
    price = models.FloatField()

    def __str__(self):
       return self.name

class OrderItem(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField(default=1)
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    ordered = models.BooleanField(default=False)

    def __str__(self):
       return f"{self.quantity} of {self.item.name}"

    @property
    def get_total_price(self):
       return self.quantity*self.item.price

And this store/tests.py:

def create_item(name='cintura', price=10):
   return Item.objects.create(name=name, price=price)

def get_user():
   return User.objects.get(username='foo')

def create_orderitem(quantity=2, user=get_user(), ordered=False):
    item = create_item()
    return OrderItem.objects.create(item=item, quantity=quantity, user=user, ordered=ordered)

class OrderItemModelTest(TestCase):

   def test_orderitem_creation(self):
       order_item = create_orderitem()
       self.assertFalse(order_item.ordered)
       self.assertGreater(order_item.quantity, 0, 'Quantity must be > 0')
       #put here user check

This is the error:

django.db.utils.IntegrityError: The row in table 'store_orderitem' with primary key '1' has an invalid foreign key: store_orderitem.user_id contains a value '1' that does not have a corresponding value in auth_user.id.

CodePudding user response:

You need something like this:

def setUp(self):
        self.user = User.objects.create_user(username='testuser', password='password')
        factory = RequestFactory()
        request = factory.get('')
        request.user = self.user
        self.client.login(username='testuser', password='password')

In your tests use self.client as a ready user.

CodePudding user response:

Django clears the database between tests. If you call your get_user() already in function's signature it gets executed before the test class. If you want to keep your structure like it is now you have to move it into the function:

def create_orderitem(quantity=2, user=None, ordered=False):
    if user is None:
        user = get_user()
    item = create_item()
    return OrderItem.objects.create(item=item, quantity=quantity, user=user, ordered=ordered)
  • Related