在Python 2.7中以二进制模式读取模拟文件

时间:2017-11-17 11:18:19

标签: python-2.7 unit-testing mocking

我试图在Python 2.7中对二进制文件进行单元测试。但悲惨地失败了。

test_my_module:

def test_read_binary(self):
    d = {
        "offset": [1, 4, 5, 7],
        "bytes" : [3, 1, 2, 3]
    }

    spec = pd.DataFrame(d)
    input_file = 'input.bin'

    fake_file = StringIO.StringIO('foo\nbar\n')
    with mock.patch('my_module.open', return_value=fake_file, create=True):
        full_spec = self._tt.read_binary(spec, input_file)

    print full_spec

my_module:

def read_binary(self, spec, input_file):
    with open(input_file, 'rb') as infile:
        def read_data(row):
            print 'ROW:', row
            infile.seek(row['offset'], 0)
            value = infile.read(row['bytes'])
            print value
            return value

        spec['raw'] = spec.apply(read_data, axis=1)

    return spec

这会产生以下异常: AttributeError:StringIO实例没有属性' 退出'

有任何建议如何去做?

1 个答案:

答案 0 :(得分:0)

作为参考,我使用以下函数解决了这个问题:

def mock_open(self, mock_o=None, data=None):
    file_spec = file
    if mock_o is None:
        mock_o = mock.MagicMock(spec=file_spec)

    handle = mock.MagicMock(spec=file_spec)
    handle.write.return_value = None
    if data is None:
        handle.__enter__.return_value = handle
    else:
        handle.__enter__.return_value = data
    mock_o.return_value = handle
    return mock_o

def test_read_binary(self):
    data = b'\x68\x65\x6c\x6c\x6f\x77\x6f\x72\x6c\x64'  # helloworld
    d = {
        'offset': [0, 4, 5, 7],
        'bytes': [3, 1, 2, 3]
    }

    spec = pd.DataFrame(d)
    input_file = 'input.bin'
    expected_list = [b'\x68\x65\x6c', b'\x6f', b'\x77\x6f', b'\x72\x6c\x64']

    m = self.mock_open(data=StringIO.StringIO(data))
    with mock.patch('__builtin__.open', m, create=True):
        full_spec = self._tt.read_binary(spec, input_file)

    self.assertListEqual(expected_list, full_spec['raw'].tolist())