模拟的时间在单元测试中传递(Simulating the passing of time in un

2019-07-29 11:00发布

我已经建立了一个客户端paywalled CMS +发票系统,我需要得到更严格的与我的测试。

我把我所有的数据在Django ORM和有一堆在不同的时间间隔,使得确保运行芹菜任务新发票和发票提醒被发送和获取的削减,当用户不支付他们的发票。

例如,我想成为一个能够运行一个测试:

  1. 创建一个新用户,并生成访问X天的发票到现场

  2. 模拟的X + 1天的传球,并运行我的一切芹菜中设置的任务。

  3. 对于另一X天一个新的发票已经向用户发出检查。

吻的方式,我拿出迄今是做一个单独的机器上的所有测试和实际操作在操作系统级别的日期/时间。 因此,测试脚本将:

  1. 设置系统日期为1天

  2. 创建一个新用户,并为接入的X天的第一张发票

  3. 然后推进系统日期1天。 运行我所有的芹菜任务。 重复,直到X + 1日子已经“过去了”

  4. 检查新发票已经发出

这是一个有点笨拙,但我认为它可能工作。 在任何其他的想法如何把它做?

Answer 1:

您可以使用模拟改变你用得到的时间(函数的返回值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类,做一切以同样的方式,除非现在被称为返回一个恒定值。



Answer 2:

如果没有使用特殊的模拟库,我建议为(可能是一个全局变量)在模拟式模式是编写的代码。 在实物模型,模式,而不是调用正常时间功能(如了time.time()或其他),你可以调用一个实体模型时,函数返回无论你在你的特殊情况下的需要。

我会投下来更改系统时间。 这似乎并不像一个单元测试,而更像一个功能测试,因为它无法并行进行,以在该机器上其他任何东西。



文章来源: Simulating the passing of time in unittesting