访问模拟类函数的调用

问题描述 投票:0回答:1

我编写了一个自定义类来模拟代码库中的通用 API 客户端,这样我就可以集中轻松地模拟所有类方法以进行单元测试。到目前为止,这工作得很好,但是我正在寻找一种方法来跟踪对每个类方法的单独调用。现在,唯一可通过 Mock 进行跟踪的调用是初始类实例化。

这是模拟课:

from faker import Factory

faker = Factory.create()

class MockAPIClass
  def get_some_data(self, data):
    return f"{data} - {faker.pyint()}"

然后在我的util文件中:

def func_to_test_that_calls_client(arg):
  client = regular_api_client()
  return client.get_some_data(arg)

然后在我的单元测试中:

from unittest import mock
from django.test import TransactionTestCase
from .file import MockAPIClass

from .util import func_to_test_that_calls_client

class TestUils(TransactionTestCase):

  def setUp(self):
    self.api_call_patcher = mock.patch('path.to.mocked.class.instantiation')
    self.patch_api = self.api_call_patcher.start()
    self.mock_api = MockAPIClass()  # this done so that the mocked class can be referenced below
    self.patch_api.return_value = self.mock_api

  def tearDown(self):
    mock.patch.stopall()

  def test_util_func(self):
    res = func_to_test_that_calls_client("test")

    self.assertTrue(res)
    self.patch_api.assert_called_once()
  

以上功能完全符合预期和预期。但是,在函数

func_to_test_that_calls_client
中,原始客户端被实例化,然后类方法
get_some_data()
被调用。通过此实现,我看不到类方法的调用堆栈,例如该函数,只能看到该类的父实例化。例如,我希望能够看到
func_to_test_that_calls_client
在当前的实现中被
"test"
调用。有没有办法用模拟或其他一些 python 技巧来做到这一点?

python django unit-testing mocking python-mock
1个回答
1
投票

一个标准的

Mock
对象(这是
patch
默认使用的对象)工作正常。无需构建您自己的特殊模拟课程。

使用它作为你的

util.py
的模拟版本(我需要添加一个虚拟的
regular_api_client
来为
patch
设定目标):

regular_api_client = lambda: None

def func_to_test_that_calls_client(arg):
  client = regular_api_client()
  return client.get_some_data(arg)

这个简单的测试似乎可以满足您的需求:

from unittest.mock import patch

from util import func_to_test_that_calls_client

def test_util_func():
    with patch('util.regular_api_client') as mock_client_class:
        mock_client = mock_client_class()
        func_to_test_that_calls_client("test")
        mock_client.get_some_data.assert_called_with("test")

请注意,您可以通过将

assert_called_with("test")
更改为
assert_called_with("something else")
并查看现在测试失败了:

E           AssertionError: expected call not found.
E           Expected: get_some_data('something else')
E           Actual: get_some_data('test')
© www.soinside.com 2019 - 2024. All rights reserved.