【问题标题】:Pass parameter to side_effect function for patching in unittest.mock将参数传递给 side_effect 函数以在 unittest.mock 中进行修补
【发布时间】:2019-01-21 21:56:30
【问题描述】:

我正在使用 unittest.mock 中的 patch 在我的测试中更改远程 API 调用的行为。

我有三个不同的函数,它们返回三个不同的json 文件,这些文件代表要从 API 返回的模拟数据。对于每个模拟 api 调用,我将 side_effect 设置为这些函数之一。这种模式不是 DRY,但我不知道如何将参数传递给 side_effect 函数。

三个mock api调用函数如下:

def mock_api_call_1():
    with open('path/to/mock_1.json') as f:
        mock_data = json.load(f)
    return mock_data

这是我的测试

class MyTest(TestCase):

    def test_api(self):

        with patch('mymodule.utils.api_call', side_effect=mock_api_call_1):
            do_crud_operations()
            self.assertEqual(MyModel.objects.all().count(), 10)

        with patch('mymodule.utils.api_call', side_effect=mock_api_call_2):
            do_crud_operations()
            self.assertEqual(MyModel.objects.all().count(), 11)

如何重构此代码以便能够将参数传递给side_effectmock_call(1) 而不是mock_call_1)。

unittest docs,我看到:

side_effect:每当调用 Mock 时都会调用的函数。看 side_effect 属性。用于引发异常或 动态改变返回值。该函数被调用 与模拟相同的参数,除非它返回默认值,否则返回 该函数的值作为返回值。

我看到传递给side_effect 的函数采用与模拟相同的参数,但我仍然不确定如何最好地使用模拟来完成此操作。我最终会想添加更多的测试用例,所以我不想硬编码不同的mock_api_call 函数。

【问题讨论】:

    标签: python unit-testing python-unittest python-mock


    【解决方案1】:

    使用 lambda 函数:

    from unittest import TestCase, main
    from unittest.mock import Mock, patch
    import sys
    
    def mock_api_call(x):
        print(x)
    
    class MyTest(TestCase):
        def test_api(self):
            with patch('sys.exit',
                        side_effect=lambda x: mock_api_call(x)) as m:
                m(0)
                sys.exit(0)
    
                m(1)
                sys.exit(1)
    
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

      【解决方案2】:

      我认为最简单的方法是将side_effect 设置为返回函数的函数。

      def mock_call(num):
          def wrapper():
              with open("path/to/mock_{num}.json") as f:
                  data = json.load(f)
              return data
          return wrapper
      

      现在我可以将mock_call(1) 传递给side_effect,它会按预期运行。

      【讨论】:

        猜你喜欢
        • 2012-04-27
        • 2014-07-27
        • 2013-01-27
        • 1970-01-01
        • 1970-01-01
        • 2021-04-18
        相关资源
        最近更新 更多