简体   繁体   English

如何在单元测试中使用python Mock side_effect作为Class方法

[英]How to use python Mock side_effect to act as a Class method in unit test

I am testing a custom API in python that makes http requests, but I don't want to make a request to the real external system every time I run the unit tests. 我在python中测试一个自定义API来发出http请求,但我不希望每次运行单元测试时都向真实的外部系统发出请求。 I am using python's mock library with a side_effect function to dynamically fake the API response. 我正在使用带有side_effect函数的python模拟库来动态伪造API响应。 How do I get the side_effect method to behave like a class method? 如何让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')

I get this error 我收到这个错误

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

but I want side_effect_func to pass api as the first argument. 但是我想让side_effect_func传递api作为第一个参数。 Appreciate any help! 感谢任何帮助!

The simplest way would probably be to just make your mock method take a single argument, then reference MyApiClass statically within the mock method itself. 最简单的方法可能是让你的mock方法接受一个参数,然后在mock方法本身内静态引用MyApiClass Otherwise, you could try mocking the class object itself (basically making a mock metaclass) or maybe using a factory that utilizes partial to build a mock class method on the fly. 否则,您可以尝试模拟类对象本身(基本上是创建一个模拟元类)或者可能使用一个使用partial的工厂来动态构建一个模拟类方法。 But if the single argument/static reference method would work for you, that seems the best to me. 但是如果单个参数/静态引用方法对你有效,那对我来说似乎是最好的。

Also, from the Mock docs, there's mocking an unbound method using patch , which looks like it may be more what you need. 此外,从模拟文档中,有一个使用补丁的模拟未绑定方法 ,看起来它可能更符合您的需要。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM