为什么我的模拟对象无法识别对它的任何调用?

时间:2017-05-04 20:18:38

标签: python unit-testing patch python-decorators assertion

这是一些单元测试,我已经简化为一个可以重现问题的最小例子。

import unittest
import zipfile
from unittest.mock import patch

"""My 'production' function"""
def list_txt_in_zipfile(zip_file_path):
    with open(zip_file_path, "rb") as file:
        zf = zipfile.ZipFile(file)
        print("zipfile.ZipFile is", zipfile.ZipFile)
    return [f_name for f_name in zf.namelist() if f_name.endswith(".txt")]


class UnzipperTest(unittest.TestCase):

    """My test method"""
    @patch("__main__.zipfile.ZipFile")
    def test_list_txt_in_zipfile(self, mock_ZipFile):
        txt_list = list_txt_in_zipfile("my.txt.zip")
        mock_ZipFile.assert_any_call() # AssertionError
        print("mock_ZipFile is", mock_ZipFile)


if __name__ == '__main__':
    unittest.main()

AssertionError:

AssertionError: ZipFile() call not found

当我的测试方法调用list_txt_in_zipfile时,它会记录一个模拟对象,而不是真正的zipfile.Zipfile(来自Python的zipfile.py)。

如果我在我的生产函数中打印那些“两个”对象zipfile.ZipFile而在我的测试方法中打印mock_ZipFile,那么它们就是同一个对象:

zipfile.ZipFile is <MagicMock name='ZipFile' id='3069297420'>
mock_ZipFile is <MagicMock name='ZipFile' id='3069297420'>

为什么mock_ZipFile无法断言对它的任何调用?

我实际上已成功测试list_txt_in_zipfile函数,将其分为两个函数(open()部分,其余部分来自zipfile.ZipFile(),但现在看来这不是巨大的功能,所以我想把这个逻辑放在一个地方。

更新:测试方法中的my.txt.zip实际存在,我还没有设法引入unittest.mock.mock_open来模拟open()因为我遇到了嘲笑{{1} }。

1 个答案:

答案 0 :(得分:3)

assert_any_call声明模拟对象已使用指定的参数调用。你没有在断言中传递任何参数,但在函数本身zipfile.Zipfile()中调用一个参数,一个文件对象。