【发布时间】:2019-01-24 10:52:35
【问题描述】:
我目前正在尝试使用管道中的 Gitlab Runner 运行测试期间 不存在 的凭据.py 模块(凭据位于 .gitignore 上)。所以实际上“模拟”必须创建credentials.py。
编辑:我猜问题是 django 系统检查 (https://docs.djangoproject.com/en/2.1/ref/checks/),它检查是否所有导入都可用。
EDIT2:我找到了一种在测试环境中防止 import_error 的方法。但我不确定这是否是在编写好代码方面的选择,这就是我没有使用 answer-function 的原因。我发现了以下 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
我的问题是,我不能只修补credentials.py 中的变量,而是必须修补整个模块并将其替换为credentials_example.py。我上面的解决方案在本地与现有的 credentials.py 一起工作,它还模拟了 credentials.py 并在测试期间用我的 credentials_example.py 替换它。但是当我删除 credentials.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'
看起来,在测试正常开始之前有一个模块的导入。但是如何模拟呢?
【问题讨论】:
-
为什么投反对票(谁给的)?请添加评论。这个问题表述得很好,问题陈述很清楚。
标签: python django unit-testing mocking