在Model方法中看不到在TestCase中创建相关对象

时间:2016-11-17 22:29:21

标签: django

我正在编写测试并且必须缺少基本的东西,因为我创建的对象似乎仍然是孤立的。

我有Customers可以容纳一些Items.在测试中,在创建属于Items的{​​{1}}(有价格)后,我要求和客户的商品价格(使用客户方法),但保持为0。

实际代码更复杂,因此我在保持结构和逻辑相同的同时简化了细节。

带有“生产”数据库的版本运行正常,因此必须有一些关于我缺少测试及其数据库的方式。

Customer

对于“生产”版本,我在管理员手动添加Joe和两个水果,并用以下方法测试:

### 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)

在这里,总数是我的预期,那么如何在测试中实现这种行为呢?

1 个答案:

答案 0 :(得分:1)

当您在item_set函数中使用compute_total时,它会在数据库中查询customer_id为ken的所有项目。 但是没有项目,并且没有ken,因为你实际上并没有将任何内容保存到数据库中。你刚刚创建了一些对象。

所以你需要做的是:

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()

首先我们需要坚持ken,以便数据库为他创建一个ID。然后我们创建苹果和香蕉,将该ID作为外键,并坚持使用它们。