【问题标题】:How to get the arguments passed to various calls from call_args_list?如何从 call_args_list 获取传递给各种调用的参数?
【发布时间】:2018-02-22 20:36:29
【问题描述】:

我正在尝试使用 call_args_list 在多次调用时获取传递给某个函数的参数。我正在使用这个:

call_args_list = mock.add_row.call_args_list

然后我得到一个如下所示的列表:[call('A', []), call('B', []), call('C', ['err'])]

如果我只想检查第二个调用在第二个参数中没有错误而第三个有错误,我需要以某种方式访问​​调用中的项目。有谁知道如何剥离这些调用对象以获取里面的项目?

【问题讨论】:

    标签: python function unit-testing testing mocking


    【解决方案1】:
    import unittest
    
    import mock
    
    
    class TestCase(unittest.TestCase):
        def test_my_func(self):
            m = mock.MagicMock()
            m.add_row('A', [])
            m.add_row('B', [])
            m.add_row('C', ['err'])
    
            calls = m.add_row.call_args_list
    
            _first_arg, second_arg = calls[1][0]
            self.assertNotEqual(second_arg, ['err'])
    
            _first_arg, second_arg = calls[2][0]
            self.assertEqual(second_arg, ['err'])
    
    
    if __name__ == '__main__':
        unittest.main()
    

    【讨论】:

      【解决方案2】:
      def test_call_args(self):
          m = mock.Mock()
          m.add_row('A', ['a', 'aa'])
          m.add_row('B', ['b', 'bb', 'bbb'])
          m.add_row('C', ['c', 'cc', 'ccc', 'err'])
      
          # args is a tuple, the second call
          args, kwargs = m.add_row.call_args_list[1]
          # the second arg is a list
          self.assertTrue('err' not in args[1])
      
          # third call
          args, kwargs = m.add_row.call_args_list[2]
          self.assertTrue('err' in args[1])
      

      【讨论】:

        【解决方案3】:

        它似乎没有(很好地)记录,但mock 定义了一个名为_Calltuple 的子类,您在call_args_list 中看到了它的实例。第一个元素是函数的名称,第二个是位置参数的元组,第三个是关键字参数的字典。

        【讨论】:

          【解决方案4】:

          有一些方法可以挖掘这些_Call 对象,但只是在某种程度上。例如,如果被调用的模拟方法中的参数本身是 Mock 怎么办?

          考虑一下:

          def test_create_and_show_main_window_should_make_main_window_vis(qtbot):
              with mock.patch('PyQt5.QtWidgets.QApplication'):
                  with mock.patch.object(MainWindow.the(), 'show') as mock_show:
                      with mock.patch('sys.exit') as mock_exit:
                          
                          main_window_class.create_and_show_main_window()
                  
              mock_show.assert_called_once()
              mock_exit.assert_called_once()
              call = mock_exit.call_args_list[0]
              call_arg = call.args[0]
              assert call_arg._extract_mock_name() == 'QApplication().exec()'
          

          在上面我想在我的应用代码中测试以下几行:

          app_instance = QtWidgets.QApplication(sys.argv)
          MainWindow.the().show()
          sys.exit(app_instance.exec())
          

          ...事实证明,在上面,call_argunittest.mock.MagicMock 类型,而 repr(call_arg) 是“<MagicMock name='QApplication().exec()' id='139817836711216'>"”。

          MagicMock 有一个name 属性,但如果您尝试直接使用它,它会自动创建一个新的MagicMock 而不是返回它:MagicMocks 是光滑的、强大的对象。幸运的是,如上图,提供了_extract_mock_name方法获取。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-14
            • 1970-01-01
            • 2011-06-24
            • 2013-06-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多