Reputation: 6057
I am in the middle of writing tests and must be missing something basic, because it appears that objects that I create remain isolated.
I have Customers
that can hold a number of Items.
Inside the test, after creating Items
(with a price) belonging to a Customer
, I want to sum the prices of the items for a Customer (using a Customer method), but keep getting 0.
The actual code is more complex, so I simplified the details while keeping the structure and logic the same.
The version with the "production" database works fine, so there must be something about the way tests and their databases are run that I am missing.
### models.py
class Customer(models.Model):
name = models.CharField(max_length=20)
def compute_total(self):
total = 0
items = self.item_set.all()
for item in items:
total += item.price
return total
def __str__(self):
return self.name
class Item(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
name = models.CharField(max_length=20)
price = models.IntegerField()
def __str__(self):
return "%s %s (%s)" % (self.customer, self.name, self.price)
### tests.py
class CustomerTests(TestCase):
def test_add_two_items(self):
ken = Customer(name="Ken")
apple = Item(customer=ken, name="apple", price=10)
banana = Item(customer=ken, name="banana", price=2)
print(apple) # make sure apple is created, and it is.
self.assertEquals(ken.compute_total(), 12)
For the "production" version, I manually add Joe and two fruits as above in the admin, and test it with:
### views.py
def index(request):
joe = Customer.objects.get(name="Joe")
return HttpResponse(joe.compute_total())
Here, the total is what I expect, so how do I achieve this behavior inside a test?
Upvotes: 0
Views: 109
Reputation: 418
What happens is when you use item_set
in compute_total
function it queries the database for all items with customer_id of ken.
But there are no items, and there is no ken because you didn't actually persisted anything into the database. You just created some objects.
So what you need to do is:
ken = Customer(name="Ken")
ken.save() # Ken must be persisted before creating his items.
apple = Item(customer=ken, name="apple", price=10)
banana = Item(customer=ken, name="banana", price=2)
apple.save()
banana.save()
First we need to persist ken, so that the database creates an ID for him. Then we create apple and banana with that id as a foreign key, and persist them as well.
Upvotes: 1