代码之家  ›  专栏  ›  技术社区  ›  Red Cricket

嘲弄assert_的_调用()未按预期工作

  •  0
  • Red Cricket  · 技术社区  · 6 年前

    我有一个单元测试,我想确保我的Django定制管理工作正在将特定消息写入其日志。

    from unittest.mock import Mock, patch
    
    ...
    
        @override_settings(HR_SYNC_DATA_DIR=f"{settings.BASE_DIR}/core/management/tests/HR_SYNC_DATA_DIR")
        @patch('core.management.commands.process_hr_changes.log')
        @patch('core.management.commands.process_hr_changes.requests.get')
        def test_sync_users2(self, mock_get, mock_log):
            #
            # Load our Mock data
            #
            test_data_dir = f"{settings.BASE_DIR}/core/management/tests/TEST_DATA_DIR"
            get_mocks = []
            for filename in glob.glob(path.join(test_data_dir, 'test-data-hrdata_underrun_page_*.json')):
                with open(filename, "r") as infile:
                    mock_response = Mock(ok=True)
                    mock_response.json.return_value = json.load(infile)
                    mock_response.status_code = status.HTTP_200_OK
                    get_mocks.append(mock_response)
            mock_get.side_effect = get_mocks
            with self.assertRaises(CommandError) as context:
                call_command('process_hr_changes')
            print(context.exception)
            self.assertEqual('percent change is -0.125 and delta_pct is 0.1. Lifecycle is dev.', context.exception.args[0])
            mock = Mock(return_value=None)
            info_calls = [
                mock.call('rehires = 0 new hires = 0 terminations = 5.'),
                mock.call('process_hr_changes args are: delta_pct 0.1 how_many_hours_back 24 dry_run False debug is False verbose is False'),
                mock.call('test: startup'),
                mock.call('Removing directory /apps/core/management/tests/HR_SYNC_DATA_DIR.'),
                mock.call('Creating directory /apps/core/management/tests/HR_SYNC_DATA_DIR.'),
                mock.call('percent change is -0.125 and delta_pct is 0.1.'),
            ]
            for mock_call in mock_log.info.mock_calls:
                print(mock_call)
            mock_log.info.assert_has_calls(info_calls, any_order=True)
    

    当我运行这个测试时,它在服务器上失败了 mock_log.info.assert_has_calls(info_calls, any_order=True) 声明中包含以下信息:

    AssertionError: (<MagicMock name='log.call()' id='140711932625744'>, <MagicMock name='log.call()' id='140711932625744'>, <MagicMock name='log.call()' id='140711932625744'>, <MagicMock name='log.call()' id='140711932625744'>, <MagicMock name='log.call()' id='140711932625744'>, <MagicMock name='log.call()' id='140711932625744'>) not all found in call list
    

    我还看到了打印语句的输出:

    call('process_hr_changes args are: delta_pct 0.1 how_many_hours_back 24 dry_run False debug is False verbose is False')
    call('test: startup')
    call('Removing directory /apps/core/management/tests/HR_SYNC_DATA_DIR.')
    call('Creating directory /apps/core/management/tests/HR_SYNC_DATA_DIR.')
    call('rehires = 0 new hires = 0 terminations = 5.')
    call('percent change is -0.125 and delta_pct is 0.1.')
    

    我做错了什么?

    谢谢

    更新:

    我必须将代码更改为:

    from unittest.mock import Mock, patch, call  # need to import call.
    
    ...
    
            info_calls = [
                call('rehires = 0 new hires = 0 terminations = 5.'),
                call('process_hr_changes args are: delta_pct 0.1 how_many_hours_back 24 dry_run False debug is False verbose is False'),
                call('test: startup'),
                call('Removing directory /apps/core/management/tests/HR_SYNC_DATA_DIR.'),
                call('Creating directory /apps/core/management/tests/HR_SYNC_DATA_DIR.'),
                call('percent change is -0.125 and delta_pct is 0.1.'),
    
            ]
            mock_log.info.assert_has_calls(info_calls, any_order=True)
    
    0 回复  |  直到 6 年前
        1
  •  2
  •   SethMMorton    6 年前

    你正在通过考试的结果 Mock.call assert_has_calls 但是 断言_有_调用 期待一个顶级的 call 对象


    请注意,在阅读了这些文件后,我同意这一点并不太清楚。这是你的文件 assert_has_calls :

    断言已使用指定的调用调用了模拟。检查模拟通话列表中的通话。

    如果任何_顺序为假,则调用必须是连续的。在指定的呼叫之前或之后可能会有额外的呼叫。

    如果任意_顺序为真,则调用可以是任意顺序,但它们必须全部出现在模拟_调用中。

    mock = Mock(return_value=None)
    mock(1)
    mock(2)
    mock(3)
    mock(4)
    calls = [call(2), call(3)]
    mock.assert_has_calls(calls)
    calls = [call(4), call(2), call(3)]
    mock.assert_has_calls(calls, any_order=True)
    

    目前还不清楚飞机在哪里 呼叫 对象来自该示例中的。我能看到混乱。

    只有当你看到 呼叫 文档说明它变得更清晰了(重点是我的):

    call()是一个帮助对象,用于生成更简单的断言,与call_args、call_args_list、mock_调用和method_调用进行比较。 call()也可以与assert_has_calls()一起使用 .