2016-11-17 47 views
0

我处于编写测试的过程中,必须缺少一些基本的东西,因为看起来我创建的对象仍然是孤立的。在模型方法中未看到在TestCase中创建相关对象

我有Customers,可以举行一些Items.测试里面,属于Customer,我要总结的项目的价格为客户(使用客户的方法)创建Items(附价格)之后,但保持为0.

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

带有“生产”数据库的版本工作正常,所以必须有关于我缺少测试及其数据库的运行方式的信息。

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

对于“生产”的版本,我手动添加乔和两个水果如上面的管理,并与测试:

### views.py 

def index(request): 
    joe = Customer.objects.get(name="Joe") 

    return HttpResponse(joe.compute_total()) 

这里,一共是我所期望的,因此如何在测试中我能达到这种行为吗?

回答

1

当您在compute_total函数中使用item_set函数时,会发生什么情况,它会在数据库中查询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() 

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

+0

是的,我记得早些时候尝试这种方法,并最终将测试数据保存到生产数据库。现在我不记得那次出了什么问题。所以我不确定这是否是正确的方法。事实证明,就像我刚才测试的那样,我将会发布一些与我自己的答案非常相似的东西。这看起来很麻烦,我希望能有一个缓和的解决方案。谢谢! –

+0

如果你想避免保存到生产数据库中,你应该使用'django.test.TestCase'而不是'unittest.TestCase'。更多信息[在这里](https://docs.djangoproject.com/en/1.10/topics/testing/overview/)。 –

+0

这是很好的信息要知道,再次感谢! –

相关问题