【问题标题】:Pytest patch field's default attribute for inherited django model继承的 Django 模型的 Pytest 补丁字段的默认属性
【发布时间】:2021-11-29 16:52:14
【问题描述】:

我在 common/models.py 中有以下模型:

from django.db import models
from uuid import uuid4

class BaseModel(models.Model):
    guid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False)

    class Meta:
       abstract = True

在 app/models.py 我有以下内容:

from django.db import models
from common.models import BaseModel

class Entity(BaseModel):
   name = models.CharField()

在测试中,我尝试通过以下方式修补 uuid4

def test_model_create(mocker):
   # Given
   mock_guid = mocker.patch("uuid.uuid4", return_value="some-guid")

   # When
   entity = Entity.objects.create(name="test_name")

   # Then
   mock_guid.assert_called_once()
   assert "some-guid" == entity.guid

mock_guid.assert_called_once() 返回未调用。这可能是什么问题?

【问题讨论】:

  • mocker.patch("common.models.uuid.uuid4", …) 呢?
  • @hoefling 我首先尝试过。但是,它没有用。

标签: python python-3.x django pytest


【解决方案1】:

我认为问题在于guid = models.UUIDField(unique=True, default=uuid.uuid4, editable=False) 在解析时直接引用了uuid.uuid4 函数。当您设置模拟时,替换此指针为时已晚。

将其更改为 guid = models.UUIDField(unique=True, default=lambda: uuid.uuid4(), editable=False) 之类的内容应该可以解决您的问题,因为该值是在运行时返回的,并且您的模拟将在函数被引用和调用之前正确设置。

【讨论】:

  • 我使用了函数而不是 lambda。因为在更改所需的字段属性迁移后,在迁移过程中它会因“无法序列化 lambda 函数”而失败。所以,我改变了它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-20
相关资源
最近更新 更多