Python-单元测试,mock类的使用

官方文档

单元测试:
https://docs.python.org/zh-cn/3/library/unittest.html (可做更多研究)

mock:
https://docs.python.org/zh-cn/3/library/unittest.mock.html?highlight=mock
https://docs.python.org/zh-cn/3/library/unittest.mock-examples.html?highlight=mock

注意点:
https://www.dazhuanlan.com/babi/topics/1315392
https://mozillazg.com/2018/03/python-introduction-mock-unit-test-examples-cookbook.html

笔记

  1. add函数还没写完,就进行单元测试

    #modular.py
    
    class Count():
    
        def add(self):
            pass
    
    # mock_demo01.py
    from unittest import mock
    import unittest
    
    from modular import Count
    
    # test Count class
    class TestCount(unittest.TestCase):
    
        def test_add(self):
            count = Count()
            count.add = mock.Mock(return_value=13)
            result = count.add(8,5)
            self.assertEqual(result,13)
    
    
    if __name__ == '__main__':
        unittest.main()
    

    count.add = mock.Mock(return_value=13)

    通过Mock类模拟被调用的方法add()方法,return_value 定义add()方法的返回值。测试通过。

  2. 补充完add函数

    #module.py
    
    class Count():
    
        def add(self, a, b):
            return a + b
    
    
    # mock_demo01.py
    from unittest import mock
    import unittest
    from module import Count
    
    
    class MockDemo(unittest.TestCase):
    
        def test_add(self):
            count = Count()
            count.add = mock.Mock(return_value=13, side_effect=count.add)
            result = count.add(8, 8)
            print(result)
            count.add.assert_called_with(8, 8)
            self.assertEqual(result, 16)
    
    if __name__ == '__main__':
        unittest.main()
    

    count.add = mock.Mock(return_value=13, side_effect=count.add)

    side_effect参数h会覆盖return_value。所以,设置side_effect参数为Count类add()方法,那么return_value的作用失效。

  3. 解决测试依赖,用于依赖可能变化的情况。

    # function.py
    def add_and_multiply(x, y):
        addition = x + y
        multiple = multiply(x, y) #注意这里依赖了multiply 
        return (addition, multiple)
    
    def multiply(x, y):
        return x * y
    
    # ok_test.py
    import unittest
    import function
    
    
    class MyTestCase(unittest.TestCase):
    
        def test_add_and_multiply(self):
            x = 3
            y = 5
            addition, multiple = function.add_and_multiply(x, y)
            self.assertEqual(8, addition)
            self.assertEqual(15, multiple)
    
    
    if __name__ == "__main__":
        unittest.main()
    

    改动multiply:

    def multiply(x, y):
        return x * y + 3
    

    再运行ok_test.py时,就会报错。解决办法

    import unittest
    from unittest.mock import patch
    import function
    
    
    class MyTestCase(unittest.TestCase):
    
        @patch("function.multiply")
        def test_add_and_multiply2(self, mock_multiply):
            x = 3
            y = 5
            mock_multiply.return_value = 15
            addition, multiple = function.add_and_multiply(x, y)
            mock_multiply.assert_called_once_with(3, 5)
    
            self.assertEqual(8, addition)
            self.assertEqual(15, multiple)
    
    
    if __name__ == "__main__":
        unittest.main()
    

    @patch(“function.multiply”)

    patch()装饰/上下文管理器可以很容易地模拟类或对象在模块测试。在测试过程中,您指定的对象将被替换为一个模拟(或其他对象),并在测试结束时还原。

    这里模拟function.py文件中multiply()函数。

    def test_add_and_multiply2(self, mock_multiply):

    在定义测试用例中,将mock的multiply()函数(对象)重命名为 mock_multiply对象。

    mock_multiply.return_value = 15

    设定mock_multiply对象的返回值为固定的15。

    ock_multiply.assert_called_once_with(3, 5)

    检查ock_multiply方法的参数是否正确。

    再次,运行测试用例,通过!

    另外, side_effect 可以是异常类或实例。 此时,调用模拟程序时将引发异常。

    如果 side_effect 是可迭代对象,则每次调用 mock 都将返回可迭代对象的下一个值。

上一篇:python Mock 模块使用说明


下一篇:mock数据 json-server