模拟django设置:AttributeError:'Settings'对象没有属性'FOO'

时间:2014-10-15 11:23:58

标签: python django unit-testing mocking django-settings

settings上的属性在使用后消失:

.... here settings.FOO does exist.

with mock.patch('django.conf.settings.FOO', 123, create=True):
    ...

... here settings.FOO is gone.

为什么会这样?

我发现了一个旧的错误,但不能相信它仍然存在,因为该错误是四年了:

http://code.google.com/p/mock/issues/detail?id=59

我们使用来自pypi的模拟1.0.1。

1 个答案:

答案 0 :(得分:0)

考虑简单的功能:

testapp/views.py

from django.conf import settings


def return_settings_foo():
    return settings.FOO

然后在shell中:

In [9]: from testapp import views

In [10]: print views.return_settings_foo()
test

In [11]: 

接下来我们将模拟settings.FOO:

In [11]: with mock.patch('testapp.views.settings.FOO', 'mocked'):
    print views.return_settings_foo()
   ....:     
mocked

因此,您必须模拟您调用它的设置模块(不是它所在的位置),对于这种情况,它是testapp/views

测试将是相同的:

import mock

from django.test import TestCase

from testapp import views

class TestPrintFoo(TestCase):
    @mock.patch('testapp.views.settings.FOO', 'mocked')
    def test_print(self):
        result = views.return_settings_foo()
        self.assertEqual(result, 'mocked')

    def test_not_mocked_print(self):
        result = views.return_settings_foo()
        self.assertEqual(result, 'test')

<小时/> 的 UPD

还有一件事。当您对存在的属性使用create=True时,无论是否存在,在__exit__的上下文结束后,它将已删除,您可以使用{{ 1}}看到了。所以你的FOO attr在上下文后被删除

pdb