我有一个非常简单的模块,像这样。
def do(url):
try:
check(url)
foo(url)
except:
bar(url)
def check(url):
# some other stuff
if ' ' in url:
raise Exception('oops')
单元测试 do
我需要嘲讽 check
,否则会有一些副作用。
from unittest.mock import patch
from main import do
def test_check_process():
with patch('main.check') as method:
do('http://something')
assert method.call_count == 1
我的问题是,我还需要(模拟的) check
函数有时会抛出一个异常。该 patch
函数能够通过该函数提供一个目标。new
关键字,但当我改成给目标函数打补丁时,我得到一个错误,如 AttributeError: 'function' object has no attribute 'call_count'
.
def mock_checker(url):
if ' ' in url:
raise Exception('oops')
def test_check_process():
with patch('main.check', new=mock_checker) as method:
do('http://something')
assert method.call_count == 1
看起来,当提供 new
参数,即 patch
上下文管理器不是一个常规的补丁对象,我根本无法窥视它。
我应该如何使用 unittest
模块?
你定义了一个新的 mock_checker
函数,它不是mock对象。该 呼叫次数 属性只存在于 unittest.mock.Mock
. 我们可以使用 副作用 为模拟对象引发一个异常。
例如
main.py
:
def do(url):
try:
check(url)
foo(url)
except:
bar(url)
def check(url):
if ' ' in url:
raise Exception('oops')
def foo(url):
pass
def bar(url):
pass
test_main.py
:
from unittest.mock import MagicMock, patch
from main import do
def test_check_process():
with patch('main.check', side_effect=Exception('oops')) as mock_check:
print(mock_check)
do('http://something')
assert mock_check.call_count == 1
def test_check_process_2():
mock_checker = MagicMock(side_effect=Exception('oops'))
with patch('main.check', new=mock_checker) as mock_check:
print(mock_check)
do('http://something')
assert mock_check.call_count == 1
if __name__ == '__main__':
test_check_process()
test_check_process_2()
执行结果。
<MagicMock name='check' id='4535123472'>
<MagicMock id='4535121168'>
断言成功