如何修复调用中的mock_open差异,但不是最终结果

Sar*_*ica 5 python json mocking

使用mock_open,我可以使用with [...] as构造从写入中捕获数据.但是,测试我所拥有的是正确的有点棘手.例如,我可以这样做:

>>> from mock import mock_open
>>> m = mock_open()
>>> with patch('__main__.open', m, create=True):
...     with open('foo', 'w') as h:
...         h.write('some stuff')
...
>>> m.mock_calls
[call('foo', 'w'),
 call().__enter__(),
 call().write('some stuff'),
 call().__exit__(None, None, None)]
>>> m.assert_called_once_with('foo', 'w')
>>> handle = m()
>>> handle.write.assert_called_once_with('some stuff')
Run Code Online (Sandbox Code Playgroud)

但我想比较一下我认为应该写的是什么.实际上是这样的:

>>> expected = 'some stuff'
>>> assert(expected == m.all_that_was_written)
Run Code Online (Sandbox Code Playgroud)

我面临的问题call是不同版本的json(2.0.9 vs 1.9)似乎以不同的方式打印.不,我不能只更新到最新的json.

我得到的实际错误是这样的:

E           AssertionError: [call('Tool_000.json', 'w'),
                             call().__enter__(),
                             call().write('['),
                             call().write('\n  '),
                             call().write('"1.0.0"'),
                             call().write(', \n  '),
                             call().write('"2014-02-27 08:58:02"'),
                             call().write(', \n  '),
                             call().write('"ook"'),
                             call().write('\n'),
                             call().write(']'),
                             call().__exit__(None, None, None)] 
            !=
                            [call('Tool_000.json', 'w'),
                             call().__enter__(),
                             call().write('[\n  "1.0.0"'),
                             call().write(', \n  "2014-02-27 08:58:02"'),
                             call().write(', \n  "ook"'),
                             call().write('\n'),
                             call().write(']'),
                             call().__exit__(None, None, None)]
Run Code Online (Sandbox Code Playgroud)

实际上,呼叫是不同的,但最终结果是相同的.

我正在测试的代码非常简单:

with open(get_new_file_name(), 'w') as fp:
    json.dump(lst, fp)
Run Code Online (Sandbox Code Playgroud)

因此,创建另一个传递文件指针的方法似乎有点过分.

and*_*and 2

您可以修补open()以返回StringIO对象,然后检查内容。

with mock.patch('module_under_test.open', create=True) as mock_open:
    stream = io.StringIO()
    # patching to make getvalue() work after close() or __exit__()
    stream.close = mock.Mock(return_value=None)
    mock_open.return_value = stream

    module_under_test.do_something() # this calls open()

    contents = stream.getvalue()
    assert(contents == expected)
Run Code Online (Sandbox Code Playgroud)

编辑:添加补丁以stream.close避免异常stream.getvalue()