15

我正在尝试模拟从文件中读取。使用示例可以通过以下结构完成:

with patch('__builtin__.open', mock_open(read_data='1'), create=True) as m:
    with open('foo') as h:
        result = h.read()

我想知道,有没有办法使用我的测试用例注释来模拟开放函数。喜欢:

@patch.object(__builtin__, 'open')
def test_check_status_running(self, m_open):

我找不到正确的方法,因为对我来说它适用于 int 而不适用于字符串:

@patch.object(__builtin__, 'open')
def test_check_status_running1(self, m_open):
    m_open = mock_open(read_data='1')
    pid = open('testfile').read().strip()
    print type(pid)                    # <class 'mock.MagicMock'>
    self.assertEqual(1, int(pid))      # Pass
    self.assertEqual('1', pid)         # Fails MismatchError: '1' != <MagicMock name='open().read()' id='39774928'>
4

2 回答 2

21

您可以通过多种方式修补该open方法。我更喜欢修补builtins.openand 将模拟对象传递给测试方法,如下所示:

from unittest.mock import patch, mock_open
from mymodule import method_that_read_with_open

class TestPatch(unittest.TestCase):
    @patch('builtins.open', new_callable=mock_open, read_data='1')
    def test_open_file(self, m):
        string_read = method_that_read_with_open()
        self.assertEqual(string_read, '1')
        m.assert_called_with('filename', 'r')

请注意,我们正在传递 mock_open 函数而不调用它!

但是因为你正在修补内置方法,你也可以这样做:

class TestPatch(unittest.TestCase):
    @patch('builtins.open', mock_open(read_data='1'))
    def test_open_file(self):
        string_read = method_that_read_with_open()
        self.assertEqual(string_read, '1')
        open.assert_called_with('filename', 'r')

这两个例子基本上是等价的:在第一个例子中,我们给 patch 方法一个工厂函数,他将调用它来创建模拟对象,在第二个例子中,我们使用已经创建的对象作为参数。

于 2016-11-29T15:59:13.477 回答
1

将 mock_open 实例分配给 new_callable 参数:

class TestClass(unittest.TestCase):
    @mock.patch('file_tested.open', new_callable=mock.mock_open())
    def test_function(self, mock_open):
        pass
于 2016-09-15T18:45:48.450 回答