我正在尝试为我的django项目运行以下单元测试:
from django.test import TestCase
from django.contrib.auth.models import User
from CarbonEmissions import models
class DbTest(TestCase):
#is called before each test case (e.g test_insertingUserProfiles)
def setUp(self):
self.user = User.objects.create(username='ppoliani')
self.userProfile = models.UserProfile.objects.create(user=self.user, title='Mr', type='student', occupation='student')
def test_insertingUserProfiles(self):
"""
Testing the insertion of user profiles into our datbase
"""
self.assertEqual(self.user.get_profile().title,'Mr')
#is called after each test case (e.g test_insertingUserProfiles)
def tearDown(self):
self.user.delete()
self.userProfile.delete()
测试未能抛出以下错误:
IntegrityError: duplicate key value violates unique constraint "CarbonEmissions_userprofile_user_id_key" DETAIL: Key (user_id)=(1) already exists.
我无法理解该代码有什么问题。
答案 0 :(得分:2)
错误消息告诉您约束“CarbonEmissions_userprofile_user_id_key”失败,因为在某些表中,已经有一行user_id等于1。
要解决这个问题,最简单的方法是使用pgAdminIII查看约束和数据,pgAdminIII通常与PostgreSQL一起安装。展开表名以查看列,约束等。展开约束以查看其名称和属性。右键单击表名,然后选择“查看数据”以查看允许您浏览数据的选项。
答案 1 :(得分:0)
也许用户配置文件对象已经被一些监听User对象的post_save信号的代码创建了?如果是这样,那么您在setUp函数中创建的配置文件是重复的。
答案 2 :(得分:0)
您尚未发布完整的堆栈跟踪(请执行!)但我认为错误位于创建UserProfile
对象的行上。在AUTH_PROFILE_MODULE
中指定配置文件类的Django文档explicitly say将不在添加新用户时自动创建该类型的模型:
方法get_profile()如果不存在,则不会创建配置文件。您需要为User模型的django.db.models.signals.post_save信号注册一个处理程序,并且在处理程序中,如果创建为True,则创建关联的用户配置文件:
因此,正如zifot建议的那样,您的项目中可能还有一些其他代码正在创建UserProfile
。如果它正确执行,只需从self.userProfile = models.UserProfile.objects.create(...
移除setUp
行,然后通过
self.user.get_profile()
答案 3 :(得分:0)
这是一个老问题,但我最近遇到了类似的问题。
我有一个模型Quote
,其中有一个名为reported
的字段。我最近将此字段更改为私有,并创建了一个属性来设置并获取它。 (因为它必须更新另一个模型,我不想通过信号或串行器来执行此逻辑。)当我更改它时,我在单元测试中得到了相同的错误。
我的模型(简化)是
class Quote(TimeStampedModel):
_reported = models.BooleanField(
default=False,
)
@property
def reported(self):
return self._reported
@reported.setter
def reported(self, value):
self._reported = value
if value:
try:
self.authorization_form.reported = True
self.authorization_form.save()
except AuthorizationForm.DoesNotExist:
pass
self.save()
我的单元测试失败是
def test_can_set_reported(self):
quote = Quote.objects.create(
reported=True,
)
为了让它通过,我将其改为
def test_can_set_reported(self):
quote = Quote.objects.create(
# reported=True,
)
quote.reported = True
quote.save()
我怀疑,问题是我在设置save()
时调用了reported
方法。因此,管理器创建了对象并设置了reported
字段(称为save),然后尝试保存实例。这可能都发生在单个事务中,因此引入了重复键。
查看堆栈跟踪是值得的,我注意到两个插入语句。
这可能表明我应该把这个逻辑转移到其他地方。 (我会这样做。)但遇到这个很有意思。