我想测试以下声明
with open('test.txt', 'w') as f:
print(['abc', 20], end='', file=f)
我试过
from __future__ import print_function
from mock import patch, mock_open
def f():
with open('test.txt', 'w') as f:
# f.write(str(['abc', 20]))
print(['abc', 20], end='', file=f)
@patch('__builtin__.open', new_callable=mock_open)
def test(mock_f):
f()
mock_f.assert_called_with('test.txt', 'w')
handle = mock_f()
handle.write.assert_called_once_with(str(['abc', 20]))
它抱怨永远不会调用write
,这是有道理的。在这种情况下,检查内容写入的正确方法是什么?
我还尝试使用f.write(str(['abc', 20]))
代替通过测试的print语句。使用print
只是一个坏主意吗?
答案 0 :(得分:1)
Python 3.6:
如果您检查模拟对象,您可以看到您正在寻找的东西就在那里。
from unittest.mock import mock_open, patch
def f():
with open('test.txt', 'w') as f:
print(['abc', 20], end='', file=f)
@patch('__main__.__builtins__.open', new_callable=mock_open)
def test(mock_f):
f()
mock_f.assert_called_with('test.txt', 'w')
print('calls to open:\n', mock_f.mock_calls, end ='\n\n')
handle = mock_f()
print('calls to the file:\n', handle.mock_calls, end ='\n\n')
print('calls to write:\n', handle.write.mock_calls, end ='\n\n')
handle.write.assert_called_once_with(str(['abc', 20]))
>>> test()
calls to open:
[call('test.txt', 'w'),
call().__enter__(),
call().write("['abc', 20]"),
call().write(''),
call().__exit__(None, None, None)]
calls to the file:
[call.__enter__(),
call.write("['abc', 20]"),
call.write(''),
call.__exit__(None, None, None)]
calls to write:
[call("['abc', 20]"), call('')]
Traceback (most recent call last):
File "<pyshell#98>", line 1, in <module>
test()
File "C:\Python36\lib\unittest\mock.py", line 1179, in patched
return func(*args, **keywargs)
File "C:/pyProjects33/test_tmp.py", line 30, in test
handle.write.assert_called_once_with(str(['abc', 20]))
File "C:\Python36\lib\unittest\mock.py", line 824, in assert_called_once_with
raise AssertionError(msg)
AssertionError: Expected 'write' to be called once. Called 2 times.
>>>
由于您传递了.write()
参数, ''
被end
第二次调用 - 您可以通过使用该参数来验证这一点。
如何测试?您可以使用assert_any_call()
:
handle.write.assert_any_call(str(['abc', 20]))
或者,如果您要验证end
参数,assert_has_calls()
:
from unittest.mock import call
....
calls = [call(str(['abc', 20])), call('')]
handle.write.assert_has_calls(calls)
您问过Is it just a bad idea to use print?
|也许其他人可以插话,但在我有限的经验中,我从未考虑过使用print()
来写一个文件。