python - 模拟单元测试中的时间流逝

标签 python testing mocking integration-testing celery

我已经为客户构建了一个付费的 CMS + 发票系统,我需要更加严格地进行测试。

我将所有数据保存在 Django ORM 中,并有一堆 Celery 任务以不同的时间间隔运行,以确保在用户不支付发票时发送新发票和发票提醒并切断访问权限。

例如,我希望能够运行以下测试:

  1. 创建一个新用户并为访问该网站的 X 天生成一张发票

  2. 模拟 X + 1 天的过去,并运行我在 Celery 中设置的所有任务。

  3. 检查是否已向用户开具另外 X 天的新发票。

到目前为止,我提出的 KISS 方法是在单独的机器上进行所有测试,并在操作系统级别实际操作日期/时间。所以测试脚本会:

  1. 将系统日期设置为第 1 天

  2. 创建一个新用户并为 X 天的访问生成第一张发票

  3. 提前 1 天然后系统日期。运行我所有的 celery 任务。重复直到 X + 1 天“过去”

  4. 检查是否已开具新发票

这有点笨拙,但我认为它可能会起作用。关于如何完成它还有其他想法吗?

最佳答案

您可以使用 mock更改用于获取时间的函数的返回值(例如 datetime.datetime.now)。

有多种方法可以做到这一点(请参阅模拟文档),但这里有一种:

import unittest
import datetime
from mock import patch

class SomeTestCase(unittest.TestCase):
    def setUp(self):
        self.time = datetime.datetime(2012, 5, 18)
        class fakedatetime(datetime.datetime):
            @classmethod
            def now(cls):
                return self.time
        patcher = patch('datetime.datetime', fakedatetime)
        self.addCleanup(patcher.stop)
        patcher.start()

    def test_something(self):
        self.assertEqual(datetime.datetime.now(), datetime.datetime(2012, 5, 18))
        self.time = datetime.datetime(2012, 5, 20)
        self.assertEqual(datetime.datetime.now(), datetime.datetime(2012, 5, 20))

因为我们不能直接替换 datetime.datetime.now,所以我们创建了一个假的 datetime 类,除了在 now 被调用时返回一个常量值之外,所有的事情都是一样的。

关于python - 模拟单元测试中的时间流逝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10652097/

相关文章:

python - 具有多处理工作人员的扭曲网络客户端?

grails - 如何将 JAR 添加到仅用于测试范围的 Grails 项目的类路径?

python - 是否有任何 python 库可以帮助测试外部 python 脚本

html - 如何从 Selenium IDE 的下拉无序列表中选择一个元素

unit-testing - 如何在 Grails 单元测试中模拟 Java 类?

python - print() 没有连接成一个字符串

python - 使用 docker-compose 的本地 dask 集群

testing - 用 mock 测试还是不用 mock 测试更好?

java - 你如何模拟 GroovyTestCase 中的方法?

python - 拆分名字和姓氏正则表达式