【问题标题】:Problems using User model in django unit tests在 django 单元测试中使用用户模型的问题
【发布时间】:2011-02-19 21:26:30
【问题描述】:

我有以下 django 测试用例,它给了我错误:

class MyTesting(unittest.TestCase):
    def setUp(self):
        self.u1 = User.objects.create(username='user1')
        self.up1 = UserProfile.objects.create(user=self.u1)

    def testA(self):
        ...

    def testB(self):
        ...

当我运行测试时,testA 将成功通过,但在testB 开始之前,我收到以下错误:

IntegrityError: column username is not unique

很明显,它试图在每个测试用例之前创建self.u1,并发现它已经存在于数据库中。如何在每个测试用例之后正确清理它,以便后续用例正常运行?

【问题讨论】:

    标签: python django unit-testing django-testing


    【解决方案1】:

    准确地说,setUp 的存在正是为了在每个测试用例之前运行一次。

    converse 方法,即在每个测试用例之后运行一次 的方法,命名为 tearDown:这就是您删除 self.u1 等的地方(大概只需调用 self.u1.delete(),除非您有除了删除对象之外的补充专门清理要求)。

    【讨论】:

      【解决方案2】:

      在每个测试用例之前和之后调用单元测试上的setUptearDown 方法。定义tearDown方法,删除创建的用户。

      class MyTesting(unittest.TestCase):
          def setUp(self):
              self.u1 = User.objects.create(username='user1')
              self.up1 = UserProfile.objects.create(user=self.u1)
      
          def testA(self):
              ...
      
          def tearDown(self):
              self.up1.delete()
              self.u1.delete()
      

      我还建议create user profiles 使用post_save 信号,除非您真的想为每个用户手动创建用户配置文件。

      跟进删除评论:

      来自Django docs

      当 Django 删除一个对象时,它 模拟 SQL 的行为 对 DELETE CASCADE 的约束——在 换句话说,任何具有 指向对象的外键 被删除将连同 它。

      在您的情况下,用户个人资料指向用户,因此您应该先删除用户才能同时删除个人资料。

      【讨论】:

      • 谢谢!我现在遇到的问题是,当我删除 up1 时,即使我已将 User 指定为 UserProfile 的外键,删除也不会级联和删除 u1。例如user = models.ForeignKey(User, unique=True)
      • 其实应该先删除用户才能级联删除用户配置文件,也可以先删除用户配置文件再删除用户。
      • 呸...我不是在文档中读到的,但由于某种原因,我对外键指向的方向感到困惑...
      • 您不应该使用 create() 创建用户。而是使用新的 create_user() 方法。这将正确地散列密码。详情在这里:docs.djangoproject.com/en/1.4/topics/auth/…
      【解决方案3】:

      如果您希望 django 在每次测试运行后自动刷新测试数据库,那么您应该扩展 django.test.TestCase,而不是 django.utils.unittest.TestCase(就像您目前所做的那样)。

      最好在每次测试后转储数据库,这样您就可以额外确保测试是一致的,但请注意,由于额外的开销,您的测试会运行得更慢。

      请参阅"Writing Tests" Django Docs 中的警告部分。

      【讨论】:

        猜你喜欢
        • 2017-12-19
        • 1970-01-01
        • 2014-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多