未调用Unittest模拟类的方法

时间:2019-12-02 11:00:05

标签: python mocking python-unittest side-effects

我是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 方法,以准备测试用例,以使未建立前四次尝试连接并建立第五次尝试连接 >。

尽管我嘲笑了该方法,但原始方法却被调用。

我的假设:

  

初始化对任何目标的模拟行为时,从新初始化的对象对此类目标进行的任何调用都将模仿修补时定义的模拟行为。

1 个答案:

答案 0 :(得分:1)

这是单元测试解决方案:

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