我是Mock测试的新手。出于学习目的,我试图模拟状态检查天气(是否建立了数据库连接),并且处理程序没有次数尝试执行数据库连接操作。
class Handler:
def is_connected(self):
# return true if connected to backend database
pass
class Backend:
def initConnection(self):
handlr = Handler()
while(True):
is_connected = handlr.is_connected()
print(is_connected)
if(is_connected):
break
class TestBackendConnection(TestCase):
def test_connection_waiting(self):
"""Test that the backend waits for connection untill the handler connects"""
with patch('side_eff.Handler.is_connected') as isconn:
bknd = Backend()
isconn.side_effect = [False] * 4 + [True]
# print(tryCon()) => False
# print(tryCon()) => False
# print(tryCon()) => False
# print(tryCon()) => False
# print(tryCon()) => True
bknd.initConnection()
self.assertEqual(isconn.call_count, 5)
我正在用side_effect修补Handler类的is_connected方法,以便准备测试用例,以使对于前四次尝试未建立连接,而对第五次尝试已建立连接。
尽管我嘲笑了该方法,但是原来的方法正在被调用。
我的假设:
在对任何目标初始化模拟行为时,从新初始化的对象对此类目标进行的任何调用都将模仿修补时定义的模拟行为。
这里是单元测试解决方案:
side_eff.py
:
class Handler:
def is_connected(self):
pass
class Backend:
def initConnection(self):
handlr = Handler()
while(True):
is_connected = handlr.is_connected()
print(is_connected)
if(is_connected):
break
test_side_eff.py
:
import unittest
from side_eff import Backend
from unittest.mock import patch
class TestBackendConnection(unittest.TestCase):
def test_connection_waiting(self):
"""Test that the backend waits for connection untill the handler connects"""
with patch('side_eff.Handler') as MockHandler:
handlerInstance = MockHandler.return_value
handlerInstance.is_connected.side_effect = [False] * 4 + [True]
bknd = Backend()
bknd.initConnection()
self.assertEqual(handlerInstance.is_connected.call_count, 5)
if __name__ == '__main__':
unittest.main()
带有覆盖率报告的单元测试结果:
(venv) ☁ python-codelab [master] ⚡ coverage run /Users/ldu020/workspace/github.com/mrdulin/python-codelab/src/stackoverflow/59137518/test_side_eff.py
False
False
False
False
True
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
(venv) ☁ python-codelab [master] ⚡ coverage report -m
Name Stmts Miss Cover Missing
---------------------------------------------------------------------------
src/stackoverflow/59137518/side_eff.py 11 1 91% 4
src/stackoverflow/59137518/test_side_eff.py 13 0 100%
---------------------------------------------------------------------------
TOTAL 24 1 96%
源代码:https://github.com/mrdulin/python-codelab/tree/master/src/stackoverflow/59137518