【问题标题】:How to use python Mock side_effect to act as a Class method in unit test如何在单元测试中使用 python Mock side_effect 作为类方法
【发布时间】:2023-03-14 13:05:01
【问题描述】:

我正在 python 中测试一个自定义 API,它发出 http 请求,但我不想每次运行单元测试时都向真实的外部系统发出请求。我正在使用带有 side_effect 函数的 python 模拟库来动态伪造 API 响应。如何让 side_effect 方法表现得像类方法?

import requests

class MyApiClass():
    def make_request(self, params):
        return requests.get('http://someurl.com', params=params)

    def create_an_object(self, params):
        return self.make_request(params)

import unittest, mock

def side_effect_func(self, params):
    if params['name'] == 'Specific Name':
        return {'text': 'Specific Action'}
    else:
        return {'text': 'General Action'}

class MyApiTest(unittest.TestCase):
    def setUp(self):
        super(MyApiTest, self).setUp()
        mocked_method = mock.Mock(side_effect=side_effect_func)
        MyApiClass.make_request = mocked_method

    def test_create_object(self):
        api = MyApiClass()
        params = {'name': 'Specific Name'}
        r = api.create_an_object(params) # Complains that two arguments are needed!
        self.assertEqual(r['text'], 'Specific Action')

我收到此错误

TypeError: side_effect_func() takes exactly 2 arguments (1 given)

但我希望 side_effect_funcapi 作为第一个参数传递。感谢任何帮助!

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    最简单的方法可能是让你的模拟方法接受一个参数,然后在模拟方法本身内静态引用MyApiClass。否则,您可以尝试模拟类对象本身(基本上是制作模拟元类),或者使用使用partial 的工厂即时构建模拟类方法。但是,如果单参数/静态引用方法对您有用,那对我来说似乎是最好的。

    此外,在 Mock 文档中,有 mocking an unbound method using patch,看起来它可能更符合您的需求。

    【讨论】:

    • 好的,谢谢!我认为用补丁模拟一个未绑定的方法是我需要的。如果没有,您对 MyApiClass 进行硬编码的建议应该可行。
    • @silas-ray 指向 Python 文档的链接中的锚不再存在,我在任何地方都找不到“未绑定”这个词(在 Python 3 的任何版本中):你能更新吗是吗?
    • @AllanLewis 是的,Python 3 一起消除了未绑定的方法。它应该只是崩溃到修补类上的函数。
    猜你喜欢
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 2020-08-29
    • 2012-02-06
    • 2020-02-17
    • 2016-11-29
    相关资源
    最近更新 更多