代码之家  ›  专栏  ›  技术社区  ›  Vino

如何模拟Python类的对象?

  •  6
  • Vino  · 技术社区  · 6 年前

    假设我在下面的课堂上;

    class CompositionClass(object):
        def __init__(self):
            self._redis = Redis()
            self._binance_client = BinanceClient()
    
        def do_processing(self, data):
            self._redis.write(data)
            self._binance_client.buy(data.amount_to_buy)
    
            # logic to actually unittest
    
            return process_val
    

    在我的应用程序中,还有其他对象将外部API作为组合调用 ComplexClass .当我在测试 do_processing ,我不想调用这些昂贵的API调用。我已经在SO和Google上彻底检查了unittesting;所有的例子都很简单,但不是很有用。在我的情况下,我如何使用 unittest.mock 要模拟这些对象?

    2 回复  |  直到 6 年前
        1
  •  3
  •   Will Keeling    6 年前

    嘲笑 Redis BinanceClient 类是使用 patch 测试类中的装饰器,例如:

    from unittest import TestCase
    from unittest.mock import patch
    from package.module import CompositionClass
    
    class TestCompositionClass(TestCase):
    
        @patch('package.module.BinanceClient')
        @patch('package.module.Redis')
        def test_do_processing(self, mock_redis, mock_binance):
            c = CompositionClass()
            data = [...]
            c.do_processing(data)
    
            # Perform your assertions
    
            # Check that mocks were called
            mock_redis.return_value.write.assert_called_once_with(data)
            mock_binance.return_value.buy.assert_called_once_with(data.amount_to_buy)
    

    请注意,指定给的路径 @patch 是包含 CompositionClass 及其进口 Redis公司 二进制客户端 。修补发生在该模块中,而不是包含 Redis公司 二进制客户端 实现本身。

        2
  •  0
  •   Konstantin    6 年前

    您需要将API调用必须返回的值设置为此函数:

    from unittest.mock import MagicMock
    
    
    class Tester(unittest.TestCase):
        def setUp(self):
            pass
    
        def test_do_processing(self):
    
            self.API_function = MagicMock(return_value='API_response')
            # test logic