Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python';s';模拟';-回应一个论点_Python_Unit Testing_Testing_Mocking - Fatal编程技术网

Python';s';模拟';-回应一个论点

Python';s';模拟';-回应一个论点,python,unit-testing,testing,mocking,Python,Unit Testing,Testing,Mocking,我需要测试一个方法,它打开两个文件并向每个文件写入不同的数据。文件的写入顺序并不重要 下面是我如何测试一个只需要打开一个文件的方法,使用替换open: from io import BytesIO import mock class MemorisingBytesIO(BytesIO): """Like a BytesIO, but it remembers what its value was when it was closed.""" def close(self):

我需要测试一个方法,它打开两个文件并向每个文件写入不同的数据。文件的写入顺序并不重要

下面是我如何测试一个只需要打开一个文件的方法,使用替换
open

from io import BytesIO
import mock

class MemorisingBytesIO(BytesIO):
    """Like a BytesIO, but it remembers what its value was when it was closed."""
    def close(self):
        self.final_value = self.getvalue()
        super(MemorisingBytesIO, self).close()

open_mock = mock.Mock()
open_mock.return_value = MemorisingBytesIO()

with mock.patch('__builtin__.open', open_mock):
    write_to_the_file()  # the function under test

open_mock.assert_called_once_with('the/file.name', 'wb')
assert open_mock.return_value.final_value == b'the data'
我在修改此方法以使用写入两个文件的方法时遇到问题。我考虑过使用
副作用
按顺序返回两个
MemorisingBytesIO
s,并断言它们中的每一个都包含正确的数据,但是测试将变得脆弱:如果方法中调用的顺序改变,测试将失败


因此,我真正想做的是,当使用一个文件名调用它时,让
open\u mock
返回一个
MemorisingBytesIO
,当使用另一个文件名调用它时,返回另一个。我已经在其他语言的模拟库中看到了这一点:在Python中,是否可以不子类化
Mock

下面的方法如何?(使用类属性保存文件内容):


从那以后,我发现了使用
mock
实现我最初想要的功能的方法。您可以将
副作用设置为等于一个函数;调用mock时,将参数传递给该函数

In [1]: import mock

In [2]: def print_it(a, b):
   ...:     print b
   ...:     print a
   ...:     

In [3]: m = mock.Mock(side_effect=print_it)

In [4]: m('hello', 2)
2
hello
下面是如何编写原始示例来处理两个文件:

fake_file_1 = MemorisingBytesIO()
fake_file_2 = MemorisingBytesIO()

def make_fake_file(filename, mode):
    if filename == 'a/b.txt':
        return fake_file_1
    elif filename == 'a/c.txt':
        return fake_file_2
    else:
        raise IOError('Wrong file name, Einstein')

open_mock = mock.Mock(side_effect=make_fake_file)
with mock.patch('__builtin__.open', open_mock):
    write_to_the_file()

assert ('a/b.txt', 'wb') in open_mock.call_args
assert ('a/c.txt', 'wb') in open_mock.call_args
assert fake_file_1.final_value == 'file 1 data'
assert fake_file_2.final_value == 'file 2 data'

如果您对我原来问题的答案感兴趣,请参阅下面我的答案:)
fake_file_1 = MemorisingBytesIO()
fake_file_2 = MemorisingBytesIO()

def make_fake_file(filename, mode):
    if filename == 'a/b.txt':
        return fake_file_1
    elif filename == 'a/c.txt':
        return fake_file_2
    else:
        raise IOError('Wrong file name, Einstein')

open_mock = mock.Mock(side_effect=make_fake_file)
with mock.patch('__builtin__.open', open_mock):
    write_to_the_file()

assert ('a/b.txt', 'wb') in open_mock.call_args
assert ('a/c.txt', 'wb') in open_mock.call_args
assert fake_file_1.final_value == 'file 1 data'
assert fake_file_2.final_value == 'file 2 data'