模拟Python的内置打印功能

ayc*_*dee 38 python unit-testing mocking python-2.x

我试过了

from mock import Mock
import __builtin__

__builtin__.print = Mock()
Run Code Online (Sandbox Code Playgroud)

但这会引发语法错误.我也试过修补它

@patch('__builtin__.print')
def test_something_that_performs_lots_of_prints(self, mock_print):

    # assert stuff
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点?

Krz*_*nko 47

我知道已经有一个已经接受的答案,但是对于这个问题有更简单的解决方案 - 在python 2.x中模拟打印.答案在模拟库教程中:http://www.voidspace.org.uk/python/mock/patch.html,它是:

>>> from StringIO import StringIO
>>> def foo():
...     print 'Something'
...
>>> @patch('sys.stdout', new_callable=StringIO)
... def test(mock_stdout):
...     foo()
...     assert mock_stdout.getvalue() == 'Something\n'
...
>>> test()
Run Code Online (Sandbox Code Playgroud)

当然你也可以使用以下断言:

self.assertEqual("Something\n", mock_stdout.getvalue())
Run Code Online (Sandbox Code Playgroud)

我在我的单元测试中检查了这个解决方案,它按预期工作.希望这有助于某人.干杯!


qua*_*tum 16

print是python 2.x中的关键字,使用它作为属性引发SyntaxError.您可以通过from __future__ import print_function在文件的开头使用来避免这种情况.

注意:您不能简单地使用setattr,因为除非print禁用该语句,否则不会调用您修改的print函数.

编辑:您还需要from __future__ import print_function在每个文件中使用您想要修改的print函数,否则它将被print语句掩盖.


Tom*_*Tom 16

这是一个更简单的Python 3解决方案 - 它更容易unittest.mock直接在内置print函数上使用,而不是摆弄sys.stdout:

from unittest.mock import patch, call

@patch('builtins.print')
def test_print(mocked_print):
    print('foo')
    print()

    assert mocked_print.mock_calls == [call('foo'), call()]
Run Code Online (Sandbox Code Playgroud)


Vla*_*den 6

from unittest.mock import patch


def greet():
    print("Hello World")


@patch('builtins.print')
def test_greet(mock_print):
    greet()
    mock_print.assert_called_with("Hello World!")
Run Code Online (Sandbox Code Playgroud)