Unittest 模拟了 class 的方法未被调用
Unittest mocked class's method not being called
我是模拟测试的新手。出于学习目的,我尝试模拟状态检查是否建立了数据库连接,以及 Handler 尝试执行数据库连接操作的次数。
class Handler:
def is_connected(self):
# return true if connected to the 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 修补处理程序 class 的 is_connected 方法,以便准备一个测试用例 前四次尝试连接未建立,第五次尝试连接建立。
虽然我mock了方法,但是调用的还是原来的方法
我的假设:
On initializing mock behavior to any target, any call made from a newly initialized object to such target mimics the mock behavior defined while patching.
单元测试解决方案如下:
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/Whosebug/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/Whosebug/59137518/side_eff.py 11 1 91% 4
src/Whosebug/59137518/test_side_eff.py 13 0 100%
---------------------------------------------------------------------------
TOTAL 24 1 96%
源代码:https://github.com/mrdulin/python-codelab/tree/master/src/Whosebug/59137518
我是模拟测试的新手。出于学习目的,我尝试模拟状态检查是否建立了数据库连接,以及 Handler 尝试执行数据库连接操作的次数。
class Handler:
def is_connected(self):
# return true if connected to the 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 修补处理程序 class 的 is_connected 方法,以便准备一个测试用例 前四次尝试连接未建立,第五次尝试连接建立。
虽然我mock了方法,但是调用的还是原来的方法
我的假设:
On initializing mock behavior to any target, any call made from a newly initialized object to such target mimics the mock behavior defined while patching.
单元测试解决方案如下:
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/Whosebug/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/Whosebug/59137518/side_eff.py 11 1 91% 4
src/Whosebug/59137518/test_side_eff.py 13 0 100%
---------------------------------------------------------------------------
TOTAL 24 1 96%
源代码:https://github.com/mrdulin/python-codelab/tree/master/src/Whosebug/59137518