注入Django进行测试和调试

时间:2012-12-26 20:41:15

标签: python django django-testing

我正在编写一个很大程度上取决于日期和时间的应用。我希望能够拥有now()today()的可注射概念。我原以为我可以编写这两个函数的自己版本来检查一些中心设置,我将其称为INJECTED_NOW。如果INJECTED_NOW为无,则上述函数只会返回datetime.datetime.now()datetime.date.today()的值。但是,如果INJECTED_NOW具有日期时间值,则上述函数将使用它来获取now()和today()。

我想知道如何存储INJECTED_NOW以便它是可变的。我希望能够在测试用例的开头设置它并在另一个测试用例之前修改它。同样,我希望能够从请求中设置它,也许使用中间件。

这种方法是否有意义,如果是这样,我应该如何存储INJECTED_NOW?我想避免数据库访问。有没有其他方法可以解决这个问题?

2 个答案:

答案 0 :(得分:4)

最近发布了一个名为FreezeGun的库,可以像你描述的那样指定日期时间:

http://stevepulec.com/freezegun/

答案 1 :(得分:3)

以下是使用mock的方法,有关mock的更多信息,请参阅docs

# this should be the code your are testing
import datetime

def one_minute_ago():
    return (datetime.datetime.now() - datetime.timedelta(seconds=60)).time()


# this would be in your tests file
import mock
import sys
import unittest

class SomeTestcase(unittest.TestCase):

    def test_one_minute_ago(self):
        real_datetime = datetime.datetime
        fake_now = datetime.datetime(2012, 12, 21, 11, 13, 13)
        with mock.patch('datetime.datetime', spec=datetime.datetime) as datetime_mock:
            datetime_mock.now.return_value = fake_now

            self.assertEqual(one_minute_ago(), datetime.time(11, 12, 13))


if __name__ == '__main__':
    sys.exit(unittest.main())

要测试它,只需将代码复制到文件中并使用Python运行它。