为了账号安全,请及时绑定邮箱和手机立即绑定

在 Python 中调用模拟方法的类的测试实例

在 Python 中调用模拟方法的类的测试实例

四季花海 2022-08-25 13:48:23
我正在模拟一个类的方法,并希望测试从中调用该方法的类的实例,以测试我的函数的创建部分是否按预期工作。在我的特定情况下,尝试写入Excel文件,我不希望发生这种情况,即do_stuffbar_instancedef create_instance(*args): return Bar(*args)class Bar(): def __init__(self, *args):  self.args = args def do_stuff(self):  passdef foo(*args): bar_instance = create_instance(*args) bar_instance.do_stuff()然后在测试文件中from unittest import TestCasefrom unittest.mock import patchfrom path.to.file import fooclass TestFoo(TestCase): @patch('path.to.file.Bar.do_stuff') def test_foo(self, mock_do_stuff):  test_args = [1]  _ = foo(*test_args)  # Test here the instance of `Bar` that `mock_do_stuff` was called from  # Something like  actual_args = list(bar_instance.args)  self.assertEqual(test_args, actual_args)我在运行后在测试函数中放置了一个中断,但是从访问它的实例的模拟方法中看不到任何方法,并且有点卡住了。我不想进一步模拟代码,因为我想确保正在创建正确的实例。foo(*test_args)BarBarBar
查看完整描述

2 回答

?
POPMUISE

TA贡献1765条经验 获得超5个赞

在代码示例中,有三件事可能需要测试:函数 、 类 和 函数 。我了解您的测试代码,因此您希望确保函数调用do_stuff返回的实例上。create_instanceBarfoofoocreate_instance


由于原始函数可以控制创建的实例,因此问题的解决方案是模拟,以便您的测试获得对移交给 foo 的对象的控制:create_instancecreate_instance


import unittest

from unittest import TestCase

from unittest.mock import patch, MagicMock

from SO_60624698 import foo


class TestFoo(TestCase):

   @patch('SO_60624698.create_instance')

   def test_foo_calls_do_stuff_on_proper_instance (

         self, create_instance_mock ):

      # Setup

      Bar_mock = MagicMock()

      create_instance_mock.return_value = Bar_mock

      # Exercise

      foo(1, 2, 3) # args are irrelevant

      # Verify

      Bar_mock.do_stuff.assert_called()


if __name__ == '__main__':

   unittest.main()

此外,您可能还希望测试参数是否正确传递给 。这可以作为单独的测试实现:foocreate_instance


...

   @patch('SO_60624698.create_instance')

   def test_foo_passes_arguments_to_create_instance (

         self, create_instance_mock ):

      # Setup

      create_instance_mock.return_value = MagicMock()

      # Exercise

      foo(1, 22, 333)

      # Verify

      create_instance_mock.assert_called_with(1, 22, 333)

当然,要完成对象生成的整个测试,您可以直接进行测试,方法是调用它并检查返回的实例,以确定它是否正确使用了其参数来构造实例。create_instanceBarBar


查看完整回答
反对 回复 2022-08-25
?
莫回无

TA贡献1865条经验 获得超7个赞

由于返回 Mock 的一个实例(或者实际上是 MagicMock,但它从其基础 - Mock 继承了相关方法),因此您有可用的assert_called_with方法,这应该可以解决问题。请注意,此方法对 / 敏感 - 您必须断言完全相同的调用。patchargskwargs

另一个注意事项:使用 patch.object 而不是在这里可能是一个更好的做法。patch


查看完整回答
反对 回复 2022-08-25
  • 2 回答
  • 0 关注
  • 54 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信