Python:为单元测试模拟文件

4

我正在为脚本中的一个函数编写单元测试,但是我在创建模拟文件时遇到了麻烦。我的函数接受一个文件名并输出它的MD5值。

def md5(file_name):
    #Function to return the md5 value of a file
    hash_md5 = hashlib.md5()
    with open(fname, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

目前我的单元测试:

import mock
class Function_to_test_TestCase(unittest.TestCase):

    def test_filename(self):
        with mock.patch('__main__.open', mock.mock_open(read_data=''), create=True) as m:
            md5_value=my_script.function_to_get_md5_value(m)

然而,我遇到了错误:
with open(fname, "rb") as f:
TypeError: coercing to Unicode: need string or buffer, MagicMock found

这种方法是创建带有相关模拟md5值的模拟文件的正确方法吗? 感谢您的建议!

你能解释一下my_script.function_to_get_md5_value(m)函数在哪里吗? 如果这是你的md5函数,为什么要用模拟参数而不是文件名来调用它? - Andrey Belyak
@AndreyBelyak 你好,这是一个更广泛的脚本中的函数,它扫描文件目录并生成包含每个文件名和md5值的清单文件。我正在为脚本中的每个函数创建单元测试,我只是想知道是否有一种方法可以在单元测试场景中创建一个简单的文件以测试我的函数。 - Catherine
我认为最简单的方法是使用带有示例数据的真实文件。您可以将其放置在测试文件夹中并添加到版本控制系统中。 - Andrey Belyak
1个回答

4

也许你应该将读取数据指定为二进制格式?这里有一个可行的示例,你可以将其粘贴到文件中并使用unittest运行:

import hashlib
from unittest import TestCase

import mock


def md5(file_name):
    hash_md5 = hashlib.md5()
    with open(file_name, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()


class MD5TestCase(TestCase):
    def test(self):
        with mock.patch('%s.open' % __name__, mock.mock_open(read_data=b'aaa'), create=True) as m:
            result = md5("lalala")
            self.assertEqual(result, '47bce5c74f589f4867dbd57e9ca9f808')

答案基于以下答案:如何使用Python中的Mock框架模拟在with语句中使用的open函数?


我似乎遇到了以下错误: “with open(fname, "rb") as f: IOError: [Errno 2] No such file or directory: 'lalala' ” 如果我使用'm',就会出现以下错误: “TypeError: coercing to Unicode: need string or buffer, MagicMock found” - Catherine
1
IOError 表示 open 调用未正确打补丁。请检查 mock.patch('XXX.open',...) 中的 XXX,应为带有函数的模块名称。 - Andrey Belyak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接