AttributeError: <module '__main__' from [..] 没有属性 'open' [英] AttributeError: <module '__main__' from [..] does not have the attribute 'open'
问题描述
我正在为 docker-py,但我似乎无法让测试正常工作.
我正在测试的函数如下所示:
def parse_env_file(env_file):"""读取以行分隔的环境文件.每行的格式应为key=value"."""环境 = []如果 os.path.isfile(env_file):使用 open(env_file, 'r') 作为 f:# 我们不能在这里使用 f.readlines() 因为它没有在 Mock 中实现对于 f.read().split('\n') 中的行:parse_line = line.strip().split('=')如果 len(parse_line) == 2 和 line[0] != '#':k = parse_line[0]v = parse_line[1]environment.append('{0}={1}'.format(k, v))返回环境
测试看起来像这样:
def test_parse_env_file_proper(self):使用 mock.patch('os.path.isfile', return_value=True):mock_env_file = 'USER=jdoe\nPASS=secret'使用 mock.patch('{}.open'.format(__name__), mock.mock_open(read_data=mock_env_file)):get_parse_env_file = parse_env_file('foobar')self.assertEqual(get_parse_env_file, ['USER=jdoe', 'PASS=secret'])
但是,当我运行测试时,出现以下错误:
======================================================================错误:test_parse_env_file_proper (__main__.UtilsTest)----------------------------------------------------------------------回溯(最近一次调用最后一次):文件tests/utils_test.py",第 102 行,在 test_parse_env_file_proper 中使用 mock.patch('{}.open'.format(__name__), mock.mock_open(read_data=mock_env_file)):文件/Users/mvip/code/private/github/docker-py/.tox/py27/lib/python2.7/site-packages/mock.py",第 1268 行,在 __enter__原始,本地 = self.get_original()文件/Users/mvip/code/private/github/docker-py/.tox/py27/lib/python2.7/site-packages/mock.py",第1242行,在get_original%s 没有属性 %r" %(目标,名称)AttributeError: <module '__main__' from 'tests/utils_test.py'>没有属性打开"
这里的任何提示都会有所帮助.
问题在于,作为内置函数,open
不能直接在模块中找到,而是作为 open
的后备代码>内置模块.
要解决这个问题,您应该在修补时包含 create=True
.
from unittest import mock使用 mock.patch(__name__+".open", mock.mock_open(read_data="data"), create=True):with open("somefile") as f:断言 f.read() == 数据"
然而,这只是修补当前模块中的open
(模块运行测试,而不是模块测试).>
所以你最好这样做:
导入单元测试从 unittest.mock 导入 mock_open,补丁导入模块_under_test定义函数():with open("somefile") as f:返回 f.read()类 MyTestCase(unittest.TestCase):def test_open(self):数据=一些数据"使用 patch.object(module_under_test, "open", mock_open(read_data=data), create=True):结果 = module_under_test.func()self.assertEqual(结果,数据)如果 __name__ == "__main__":单元测试.main()
I'm working on writing a test for a module for docker-py, but I can't seem to get the test to work properly.
The function I'm testing looks as follows:
def parse_env_file(env_file):
"""
Reads a line-separated environment file.
The format of each line should be "key=value".
"""
environment = []
if os.path.isfile(env_file):
with open(env_file, 'r') as f:
# We can't use f.readlines() here as it's not implemented in Mock
for line in f.read().split('\n'):
parse_line = line.strip().split('=')
if len(parse_line) == 2 and line[0] != '#':
k = parse_line[0]
v = parse_line[1]
environment.append('{0}={1}'.format(k, v))
return environment
The test then looks like this:
def test_parse_env_file_proper(self):
with mock.patch('os.path.isfile', return_value=True):
mock_env_file = 'USER=jdoe\nPASS=secret'
with mock.patch('{}.open'.format(__name__), mock.mock_open(read_data=mock_env_file)):
get_parse_env_file = parse_env_file('foobar')
self.assertEqual(get_parse_env_file, ['USER=jdoe', 'PASS=secret'])
When I run the test however, I get the following error:
======================================================================
ERROR: test_parse_env_file_proper (__main__.UtilsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "tests/utils_test.py", line 102, in test_parse_env_file_proper
with mock.patch('{}.open'.format(__name__), mock.mock_open(read_data=mock_env_file)):
File "/Users/mvip/code/private/github/docker-py/.tox/py27/lib/python2.7/site-packages/mock.py", line 1268, in __enter__
original, local = self.get_original()
File "/Users/mvip/code/private/github/docker-py/.tox/py27/lib/python2.7/site-packages/mock.py", line 1242, in get_original
"%s does not have the attribute %r" % (target, name)
AttributeError: <module '__main__' from 'tests/utils_test.py'> does not have the attribute 'open'
Any pointers here would be helpful.
The problem is that, as a builtin, open
isn't directly found in the module, but rather as fallback in the builtins
module.
To get around this you should include create=True
when patching.
from unittest import mock
with mock.patch(__name__+".open", mock.mock_open(read_data="data"), create=True):
with open("somefile") as f:
assert f.read() == "data"
However, this only patches open
in the current module (the module running the test, not the module under test).
So you'd be better off doing:
import unittest
from unittest.mock import mock_open, patch
import module_under_test
def func():
with open("somefile") as f:
return f.read()
class MyTestCase(unittest.TestCase):
def test_open(self):
data = "some data"
with patch.object(module_under_test, "open", mock_open(read_data=data), create=True):
result = module_under_test.func()
self.assertEqual(result, data)
if __name__ == "__main__":
unittest.main()
这篇关于AttributeError: <module '__main__' from [..] 没有属性 'open'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!