sim*_*ack 4 unit-testing mocking python-3.x
可以通过以下方式模拟打印:
import unittest
import builtin
class TestSomething(unittest.TestCase):
@mock.patch('builtins.print')
def test_method(self, print_):
some_other_module.print_something()
Run Code Online (Sandbox Code Playgroud)
但是这意味着在python调试控制台(pydev调试器)和单元测试方法本身print不能使用.这很不方便.
有没有办法只在模拟print方法some_other_module而不是在测试模块中?
避免这种情况的一种方法是将测试模块中的print使用与其他一些刚调用的函数交换print,如果事实证明没有更好的解决方案,我可以这样做.
@ michele的"最终解决方案"有一个更清晰的选择,在我的情况下有效:
from unittest import TestCase
from unittest.mock import patch
import module_under_test
class MyTestCase(TestCase):
@patch('module_under_test.print', create=True)
def test_something(self, print_):
module_under_test.print_something()
print_.assert_called_with("print something")
Run Code Online (Sandbox Code Playgroud)
是的你可以!...但仅仅因为您使用的是Python 3.在Python 3中print是一个函数,您可以在不更改名称的情况下重写它.为了理解最终解决方案,我将逐步描述它以获得最终的灵活且非侵入性的解决方案.
诀窍是在你的模块的顶部添加你将测试一行如下:
print = print
Run Code Online (Sandbox Code Playgroud)
现在你可以修补print你的模块了.我写了一个测试用例,其中mock_print_module.py:
print = print
def print_something():
print("print something")
Run Code Online (Sandbox Code Playgroud)
和测试模块(我autospec=True只是为了避免错误mock_print.asser_called_with):
from unittest import TestCase
from unittest.mock import patch
import mock_print_module
class MyTestCase(TestCase):
@patch("mock_print_module.print",autospec=True)
def test_something(self,mock_print):
mock_print_module.print_something()
mock_print.assert_called_with("print something")
Run Code Online (Sandbox Code Playgroud)
您只需使用以下属性即可使用patchon "builtins.print"而不会丢失打印功能side_effect patch:
@patch("builtins.print",autospec=True,side_effect=print)
def test_somethingelse(self,mock_print):
mock_print_module.print_something()
mock_print.assert_called_with("print something")
Run Code Online (Sandbox Code Playgroud)
现在,您可以跟踪您的打印调用,而不会丢失日志记录和pydev调试器.这种方法的缺点是你必须对抗很多噪音,以检查你感兴趣的打印电话.此外,您无法选择要修补的模块和不修补的模块.
因为如果你使用不能同时使用的方式共同print=print您的模块中保存builtins.print的print变量在加载模块的时间.现在,当您修补builtins.print模块时,仍然使用原始保存的模块.
如果你有机会同时使用它们,你必须包装原始印刷品而不是记录它.实现它的一种方法是使用以下代替print=print:
import builtins
print = lambda *args,**kwargs:builtins.print(*args,**kwargs)
Run Code Online (Sandbox Code Playgroud)
我们真的需要修改原始模块才有机会修补其中的所有打印调用吗?不,我们无需更改模块即可完成测试.我们唯一需要的是print在模块中注入一个局部函数来覆盖它builtins的一个:我们可以在测试模块而不是模块中进行测试.我的例子将成为:
from unittest import TestCase
from unittest.mock import patch
import mock_print_module
import builtins
mock_print_module.print = lambda *args,**kwargs:builtins.print(*args,**kwargs)
class MyTestCase(TestCase):
@patch("mock_print_module.print",autospec=True)
def test_something(self,mock_print):
mock_print_module.print_something()
mock_print.assert_called_with("print something")
@patch("builtins.print",autospec=True,side_effect=print)
def test_somethingelse(self,mock_print):
mock_print_module.print_something()
mock_print.assert_called_with("print something")
Run Code Online (Sandbox Code Playgroud)
并且mock_print_module.py可以是干净的原始版本,只需:
def print_something():
print("print something")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2758 次 |
| 最近记录: |