我在Python中有一个看起来像这样的方法(在comicfile.py
中):
from zipfile import ZipFile
...
class ComicFile():
...
def page_count(self):
"""Return the number of pages in the file."""
if self.file == None:
raise ComicFile.FileNoneError()
if not os.path.isfile(self.file):
raise ComicFile.FileNotFoundError()
with ZipFile(self.file) as zip:
members = zip.namelist()
pruned = self.prune_dirs(members)
length = len(pruned)
return length
我正在尝试为此编写一个单元测试(我已经测试过prune_dirs
),所以这就是我所拥有的(test_comicfile.py
):
import unittest
import unittest.mock
import comicfile
...
class TestPageCount(unittest.TestCase):
def setUp(self):
self.comic_file = comicfile.ComicFile()
@unittest.mock.patch('comicfile.ZipFile')
def test_page_count(self, mock_zip_file):
# Store as tuples to use as dictionary keys.
members_dict = {('dir/', 'dir/file1', 'dir/file2'):2,
('file1.jpg', 'file2.jpg', 'file3.jpg'):3
}
# Make the file point to something to prevent FileNoneError.
self.comic_file.file = __file__
for file_tuple, count in members_dict.items():
mock_zip_file.return_value.namelist = list(file_tuple)
self.assertEqual(count, self.comic_file.page_count())
当我运行此测试时,我得到以下内容:
F..ss....
======================================================================
FAIL: test_page_count (test_comicfile.TestPageCount)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.1/Frameworks/Python.framework/Versions/3.5/lib/python3.5/unittest/mock.py", line 1157, in patched
return func(*args, **keywargs)
File "/Users/chuck/Dropbox/Projects/chiv/chiv.cbstar/test_comicfile.py", line 86, in test_page_count
self.assertEqual(count, self.comic_file.page_count())
AssertionError: 2 != 0
----------------------------------------------------------------------
Ran 9 tests in 0.010s
FAILED (failures=1, skipped=2)
好的,self.comic_file.page_count()
正在返回0
。我尝试将members = zip.namelist()
放在page_count
之后放置以下行。
print('\nmembers -> ' + str(members))
在测试期间,我得到了这个:
members -> <MagicMock name='ZipFile().__enter__().namelist()' id='4483358280'>
我对单元测试很陌生并且在使用unittest.mock
时非常模糊,但我的理解是mock_zip-file.return_value.namelist = list(file_tuple)
应该使namelist
方法ZipFile
方法file_tuple
1}}类依次返回每个namelist
内容。 做什么我不知道。
我认为我在这里要做的很清楚,但我似乎无法弄清楚如何覆盖ZipFile
方法,以便我的单元测试只测试这一个函数而不是必须也可以处理preg_
。
答案 0 :(得分:2)
ZipFile
被实例化为context manager。至mock,您必须引用其__enter__
方法。
mock_zip_file.return_value.__enter__.return_value.namelist.return_value = list(file_tuple)
您尝试做的事情非常明确,但上下文管理器会增加模拟的复杂性。
一个技巧是当一个模拟注册所有调用它时,在这个例子中它说它有一个调用:
members -> <MagicMock name='ZipFile().__enter__().namelist()' id='4483358280'>
这可以指导您注册模拟对象,将所有()
替换为return_value