1

我是新手,试图让我的单元测试通过,但 DateTimeField 有问题。

在我的设置中,我设置了 USE_TZ = True 和 TIME_ZONE 。

使用 MongoDb。

首先,测试给了我一个错误,抱怨比较原始偏移和偏移感知。将 auto_now_add=True 更改为 datetime.datetime.utcnow().replace(tzinfo=utc))

我仍然无法为我的 TIME_ZONE 找到正确的时间和日期。

在我将这些放入我的数据库(settings.py)之后

'OPTIONS' : {
    'tz_aware' : True, 
}

现在我可以更改我的 TIME_ZONE 并且时间和日期显示我的本地时间,而不是 UTC。

但是当我运行一个测试模型时:

nf.data_emissao = timezone.now()
...

#check if the nf is in database
lista_nfse = Nfse.objects.all()
self.assertEquals(lista_nfse.count(), 1)

nfse_no_banco = lista_nfse[0]
...
self.assertEquals( nfse_no_banco.data_emissao, nf.data_emissao)

我的测试失败:

AssertionError: datetime.datetime(2013, 8, 10, 2, 49, 59, 391000, tzinfo=
<bson.tz_util.FixedOffset object at 0x2bdd1d0>) != datetime.datetime(2013, 8, 10, 2, 49, 59, 
391122, tzinfo=<UTC>)

我看到了 391000 和 391122 之间的差异,但不知道如何解决。

4

1 回答 1

3

问题看起来是您正在比较在两个不同时间点分配给“现在”时间的两个值。

由于时间的不断变化,在尝试断言确切的日期值时,编写单元测试以使用自动生成的日期总是很棘手。但是,有一些技术可以用来帮助在这些场景中创建可靠的测试:

  • 如果您尝试断言“nfse_no_banco.data_emissao包含现在的时间”,而不是尝试断言确切的值,您可以断言时间字段值落在最后 x 毫秒的时间内。这使您能够获得相当程度的信心,即字段中的值在分配时是“现在”,但缺点是 (a) 如果测试的执行时间恰好比x 毫秒,并且 (b) 如果由于某种原因,由于编程错误(极不可能)将值错误地分配到非常接近现在的时间,则测试将返回误报。

  • 您可以猴子补丁datetime.datetime.utcnow到您自己的方法版本,该方法返回一个预设值以进行测试,然后断言该值已分配给nfse_no_banco.data_emissao. 缺点是它增加了测试设置和拆卸的一些复杂性。但是,如果您的断言的目标是验证该字段是否已经分配了现在的时间,那么它应该会产生一个很好的测试。

  • 您可以简单地断言该字段的值不为 null (使用self.assertNotNull(nfse_no_banco.data_emissao)) - 尽管这是一个弱得多的断言,但在您使用某些框架功能(例如auto_now_add=True在 Django 中)的情况下,这通常就足够了 - 当然主要这个测试的好处是它非常简单和可靠。

最好的方法实际上取决于您要断言的内容。从您的问题看来,您确实是在试图断言nfse_no_banco.data_emissao现在分配了时间,并且您自己正在执行此操作(而不是依靠框架为您执行此操作),因此第二种方法最有意义。

下面是伪代码,展示了如何在测试中执行此操作:

# Create a constant with a fixed value for utcnow
NOW = datetime.datetime.utcnow()

# Define a test method to replace datetime.datetime.utcnow
def utcnow_fixed_value():
    return NOW

class MyTest(TestCase):

    def setUp(self):
        # Replace the real version of utcnow with our test version
        self.real_utcnow = datetime.datetime.utcnow
        datetime.datetime.utcnow = utcnow_fixed_value

    def tearDown(self):
        # Undo the monkey patch and replace the real version of utcnow
        datetime.datetime.utcnow = self.real_utcnow

    def test_value_is_now(self):
        lista_nfse = Nfse.objects.all()
        self.assertEquals(lista_nfse.count(), 1)

        nfse_no_banco = lista_nfse[0]
        ...
        self.assertEquals(NOW, nfse_no_banco.data_emissao)
于 2013-08-11T19:03:29.637 回答