热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

嘲笑默认=时区。对于单元测试-Mockingdefault=timezone.nowforunittests

Imtryingtowriteunittestsforadjangoappthatdoesalotofdatetimeoperations.Ihaveinsta

I'm trying to write unit tests for a django app that does a lot of datetime operations. I have installed mock to monkey patch django's timezone.now for my tests.

我正在为django应用程序编写单元测试,该应用程序执行大量的datetime操作。我为monkey patch django的时区安装了mock。现在对我的测试。

While I am able to successfully mock timezone.now when it is called normally (actually calling timezone.now() in my code, I am not able to mock it for models that are created with a DateTimeField with default=timezone.now.

当我能够成功模拟时区时。现在,在我的代码中,当它被正常调用时(实际上是调用timezone.now()时,我无法对使用默认=timezone.now的DateTimeField创建的模型进行模拟。


I have a User model that contains the following:

我的用户模型包含以下内容:

from django.utils import timezone
...
timestamp = models.DateTimeField(default=timezone.now)
modified = models.DateTimeField(default=timezone.now)
...
def save(self, *args, **kwargs):
    if kwargs.pop('modified', True):
        self.modified = timezone.now()
    super(User, self).save(*args, **kwargs)

My unit test looks like this:

我的单元测试是这样的:

from django.utils import timezone

def test_created(self):
    dt = datetime(2010, 1, 1, tzinfo=timezone.utc)
    with patch.object(timezone, 'now', return_value=dt):
        user = User.objects.create(username='test')
        self.assertEquals(user.modified, dt)
        self.assertEquals(user.timestamp, dt)

assertEquals(user.modified, dt) passes, but assertEquals(user.timestamp, dt) does not.

assertequal(用户。修改,dt)通过,但是assertEquals(用户)。时间戳,dt)没有。

How can I mock timezone.now so that even default=timezone.now in my models will create the mock time?

我怎么能模拟时区呢?现在,即使是default=timezone。在我的模型中会创建模拟时间吗?


Edit

编辑

I know that I could just change my unit test to pass a timestamp of my choice (probably generated by the mocked timezone.now)... Curious if there is a way that avoids that though.

我知道我可以更改我的单元测试来通过我所选择的时间戳(可能是由模拟的timezone生成的)……我很好奇是否有什么方法可以避免这种情况。

4 个解决方案

#1


11  

I just ran into this issue myself. The problem is that models are loaded before mock has patched the timezone module, so at the time the expression default=timezone.now is evaluated, it sets the default kwarg to the real timezone.now function.

我自己也遇到了这个问题。问题是模型是在mock修补了时区模块之前加载的,所以在表达式default=timezone时。现在进行评估,它将默认的kwarg设置为真正的时区。现在的功能。

The solution is the following:

解决办法如下:

class MyModel(models.Model):
    timestamp = models.DateTimeField(default=lambda: timezone.now())

#2


6  

Here's a method you can use that doesn't require altering your non-test code. Just patch the default attributes of the fields you want to affect. For example--

这里有一个不需要修改非测试代码的方法。只需修补您想要影响的字段的默认属性。例如——

field = User._meta.get_field('timestamp')
mock_now = lambda: datetime(2010, 1, 1)
with patch.object(field, 'default', new=mock_now):
    # Your code here

You can write helper functions to make this less verbose. For example, the following code--

您可以编写帮助函数来减少这种冗长。例如,下面的代码—

@contextmanager
def patch_field(cls, field_name, dt):
    field = cls._meta.get_field(field_name)
    mock_now = lambda: dt
    with patch.object(field, 'default', new=mock_now):
        yield

would let you write--

会让你写——

with patch_field(User, 'timestamp', dt):
    # Your code here

Similarly, you can write helper context managers to patch multiple fields at once.

类似地,您可以编写助手上下文管理器来一次修补多个字段。

#3


0  

Looks like you are patching timezone in the wrong place.

看起来你是在错误的地方修补时区。

Assuming your User model lives in myapp\models.py and you want to test save() in that file. The problem is that when you from django.utils import timezone at the top, it imports it from django.utils. In your test you are patching timezone locally, and it has no effect on your test, since module myapp\models.py already has a reference to the real timezone and it looks like our patching had no effect.

假设您的用户模型生活在myapp\模型中。py需要在该文件中测试save()。问题是当你来自django的时候。在顶部的utils导入时区,它从django.utils导入。在您的测试中,您正在本地修补时区,它对您的测试没有影响,因为模块myapp\models。py已经提到了实际时区,看起来我们的补丁没有效果。

Try patching timezone from myapp\models.py, something like:

尝试从myapp\模型中修补时区。py,类似:

import myapp.models.timezone

def test_created(self):
    with patch('myapp.models.timezone') as mock_timezone:
        dt = datetime(2010, 1, 1, tzinfo=timezone.utc)
        mock_timezone.now.return_value = dt

        assert myapp.models.timezone.now() == dt

        user = User.objects.create(username='test')
        self.assertEquals(user.modified, dt)
        self.assertEquals(user.timestamp, dt)

#4


0  

There is another easy way to do the above thing.

还有另一种简单的方法。

import myapp.models.timezone
from unittest.mock import patch

@patch('django.utils.timezone.now')
def test_created(self, mock_timezone):
    dt = datetime(2010, 1, 1, tzinfo=timezone.utc)
    mock_timezone.return_value = dt
    user = User.objects.create(username='test')

    self.assertEquals(user.modified, dt)
    self.assertEquals(user.timestamp, dt)

This is the best way to mock timezone.now.

这是模拟时间的最好方法。


推荐阅读
  • 利用python爬取豆瓣电影Top250的相关信息,包括电影详情链接,图片链接,影片中文名,影片外国名,评分,评价数,概况,导演,主演,年份,地区,类别这12项内容,然后将爬取的信息写入Exce ... [详细]
  • 本文介绍如何使用 Python 的 DOM 和 SAX 方法解析 XML 文件,并通过示例展示了如何动态创建数据库表和处理大量数据的实时插入。 ... [详细]
  • 本文详细介绍了如何在 Django 项目中使用 Admin 管理后台,包括创建超级用户、启动项目、管理数据模型和修改用户密码等步骤。 ... [详细]
  • 第二十五天接口、多态
    1.java是面向对象的语言。设计模式:接口接口类是从java里衍生出来的,不是python原生支持的主要用于继承里多继承抽象类是python原生支持的主要用于继承里的单继承但是接 ... [详细]
  • MySQL Decimal 类型的最大值解析及其在数据处理中的应用艺术
    在关系型数据库中,表的设计与SQL语句的编写对性能的影响至关重要,甚至可占到90%以上。本文将重点探讨MySQL中Decimal类型的最大值及其在数据处理中的应用技巧,通过实例分析和优化建议,帮助读者深入理解并掌握这一重要知识点。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • 属性类 `Properties` 是 `Hashtable` 类的子类,用于存储键值对形式的数据。该类在 Java 中广泛应用于配置文件的读取与写入,支持字符串类型的键和值。通过 `Properties` 类,开发者可以方便地进行配置信息的管理,确保应用程序的灵活性和可维护性。此外,`Properties` 类还提供了加载和保存属性文件的方法,使其在实际开发中具有较高的实用价值。 ... [详细]
  • 本文详细介绍了在 Oracle 数据库中使用 MyBatis 实现增删改查操作的方法。针对查询操作,文章解释了如何通过创建字段映射来处理数据库字段风格与 Java 对象之间的差异,确保查询结果能够正确映射到持久层对象。此外,还探讨了插入、更新和删除操作的具体实现及其最佳实践,帮助开发者高效地管理和操作 Oracle 数据库中的数据。 ... [详细]
  • 本文介绍了UUID(通用唯一标识符)的概念及其在JavaScript中生成Java兼容UUID的代码实现与优化技巧。UUID是一个128位的唯一标识符,广泛应用于分布式系统中以确保唯一性。文章详细探讨了如何利用JavaScript生成符合Java标准的UUID,并提供了多种优化方法,以提高生成效率和兼容性。 ... [详细]
  • 本文深入探讨了CGLIB BeanCopier在Bean对象复制中的应用及其优化技巧。相较于Spring的BeanUtils和Apache的BeanUtils,CGLIB BeanCopier在性能上具有显著优势。通过详细分析其内部机制和使用场景,本文提供了多种优化方法,帮助开发者在实际项目中更高效地利用这一工具。此外,文章还讨论了CGLIB BeanCopier在复杂对象结构和大规模数据处理中的表现,为读者提供了实用的参考和建议。 ... [详细]
  • 利用Flask框架进行高效Web应用开发
    本文探讨了如何利用Flask框架高效开发Web应用,以满足特定业务需求。具体案例中,一家餐厅希望每天推出不同的特色菜,并通过网站向顾客展示当天的特色菜。此外,还增加了一个介绍页面,在bios路径下详细展示了餐厅主人、厨师和服务员的背景和简介。通过Flask框架的灵活配置和简洁代码,实现了这一功能,提升了用户体验和餐厅的管理水平。 ... [详细]
  • MySQL:不仅仅是数据库那么简单
    MySQL不仅是一款高效、可靠的数据库管理系统,它还具备丰富的功能和扩展性,支持多种存储引擎,适用于各种应用场景。从简单的网站开发到复杂的企业级应用,MySQL都能提供强大的数据管理和优化能力,满足不同用户的需求。其开源特性也促进了社区的活跃发展,为技术进步提供了持续动力。 ... [详细]
  • MySQL 数据操作:增、删、查、改全面解析
    MySQL 数据操作:增、删、查、改全面解析 ... [详细]
  • 深入学习 Python 中的 xlrd 模块:掌握 Excel 文件读取技巧
    本文深入探讨了 Python 中的 xlrd 模块,重点介绍了如何高效读取 Excel 文件(包括 xlsx 和 xls 格式)。同时,文章还详细讲解了 xlwt 模块在 Excel 文件写操作中的应用。此外,文中列举了常见单元格数据类型及其处理方法,为读者提供了全面的实践指导。 ... [详细]
  • 在Python 3中,Pandas库是处理时间序列数据的强大工具。本文将详细介绍如何利用Pandas的各种功能高效地进行时间数据的清洗、转换和分析。通过具体的示例和代码片段,读者可以掌握如何读取、格式化、重采样和可视化时间数据,从而提升数据处理的效率和准确性。 ... [详细]
author-avatar
大市低开_127
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有