模拟用于Django测试用例的整个python模块

时间:2019-01-24 10:52:35

标签: python django unit-testing mocking

我目前正在尝试在管道中使用Gitlab Runner运行它们时在测试过程中不存在的凭据.py模块(凭据位于.gitignore上)。因此,实际上,“模拟”必须创建certificate.py。

编辑:我想问题是django系统检查(https://docs.djangoproject.com/en/2.1/ref/checks/),它检查所有导入是否可用。

EDIT2:我找到了一种在测试环境中防止import_error的方法。但是我不确定这是否是在编写良好代码方面的选择,这就是为什么我不使用答案功能的原因。我发现了以下stackoverflow问题:Python: Mock a module without importing it or needing it to exist,并使用第一个答案中的建议来更改我在views.py中的代码:

try:
   from battery_upgrade_web import credentials
except ImportError:
   from battery_upgrade_web import credentials_example as credentials

credentials_example在Gitlab中已存在,为空。这样,它就可以在Gitlab Runner中成功进行所有测试。

我的test_views.py如下:

@patch('battery_upgrade_web.views.BatteryUpgradeView.credentials', new=credentials_example)
class IndexViewTest(TestCase):

    @patch('battery_upgrade_web.views.BatteryUpgradeView.credentials', new=credentials_example)
    def setUp(self):
        # A client simulates a user interacting with the code at the view level
        # Lot of working mocks
        self.c = Client()

    @patch('battery_upgrade_web.views.credentials', new=credentials_example)
    def test_valid_data(self):
        resp = self.c.post('/', data={'parameter': 324})

我的views.py

from battery_upgrade_web import credentials

class BatteryUpgradeView(generic.TemplateView):
    def post(self, request, *args, **kwargs):
    #lot of code to execute

我的问题是,我不仅要修补adsp.py中的变量,还必须修补整个模块,并用certificate_example.py替换它。我上面的解决方案在本地使用现有的certificate.py进行工作,它还模拟了凭据.py,并在测试过程中将其替换为我的certificate_example.py。但是,当我删除凭据.py时,运行>python web/manage.py test battery_upgrade_web时测试会抛出以下错误消息:

Creating test database for alias 'default'...
Traceback (most recent call last):
File "web/manage.py", line 16, in <module>
    execute_from_command_line(sys.argv)
    # lot of tracebacks
File "C:\Users\e\AppData\Local\Continuum\anaconda2\envs\BatteryUpgrade36\lib\importlib\__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_loal
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "C:\Users\e\Projects\BatteryUpgrade\web\battery_upgrade_web\urls.py", line 21, in <module>
from battery_upgrade_web.views import BatteryUpgradeView
File "C:\Users\e\Projects\BatteryUpgrade\web\battery_upgrade_web\views.py", line 11, in <module>
from battery_upgrade_web import credentials
ImportError: cannot import name 'credentials'

在测试开始之前,似乎已经导入了模块。但是如何模拟呢?

1 个答案:

答案 0 :(得分:0)

我可以为您提供工作指导:

def setUp(self):
    model_mocked = MagicMock()
    model_mocked.credentials.return_value = {}
    modules = {'battery_upgrade_web': model_mocked}
    patch.dict('sys.modules', modules).start()

这将创建一个添加凭据对象的MagicMock,并将其添加到您可以导入的模块(sys.modules)列表中。

不确定它是否对您有用,但是不确定这样做的方式。