1

我正在尝试使用 python 模拟库模拟文件。虽然很简单,但我仍然不明白如何在必须接收大小参数时模拟读取函数。我试图使用 side_effect 创建一个替代函数,该函数将读取作为值传递的足够数据。

这是这样的想法:

def mock_read(value):
    test_string = "abcdefghijklmnopqrs"

    '''
     Now it should read enough values from the test string, but 
     I haven't figured out a way to store the position where the
     "read" method has stopped.
    '''

mock_file = MagicMock(spec=file)
mock_file.read.side_effect = mock_read

但是,我还没有弄清楚如何将阅读器的当前位置存储在 side_effect 函数中,然后再阅读。我认为可能有更好的方法,但我仍然想通了。

4

1 回答 1

3

不幸mock_open的是不支持部分读取,而且您使用 python 2.7(我假设它是因为您编写MagicMock(spec=file))并且mock_open非常有限。

我们可以概括您的问题,例如我们可以写出side_effect可以保持状态的内容。在 python 中有一些方法可以做到这一点,但恕我直言,最简单的是使用一个实现的类__call__(这里不能使用生成器,因为mock解释生成器就像副作用列表一样):

from mock import MagicMock

class my_read_side_effect():
    def __init__(self,data=""):
        self._data = data
    def __call__(self, l=0): #That make my_read_side_effect a callable
        if not self._data:
            return ""
        if not l:
            l = len(self._data)
        r, self._data = self._data[:l], self._data[l:]
        return r

mock_file = MagicMock(spec=file)
mock_file.read.side_effect = my_read_side_effect("abcdefghijklmnopqrs")
assert "abcdef" == mock_file.read(6)
assert "ghijklm" == mock_file.read(7)
assert "nopqrs" == mock_file.read()

此外,我们可以在处理程序中注入该实现mock_open以修补mock_open.read()方法。

from mock patch, mock_open

with patch("__builtin__.open", new_callable=mock_open) as mo:
    mock_file = mo.return_value
    mock_file.read.side_effect = my_read_side_effect("abcdefghijklmnopqrs")
    assert "abcdef" == mock_file.read(6)
    assert "ghijklm" == mock_file.read(7)
    assert "nopqrs" == mock_file.read()

这为您提供了一种在测试中使用它的简单方法,其中文件在函数中打开并且不作为参数传递。

于 2015-02-03T14:38:26.830 回答