微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

模拟Python类的方法和属性的子集

如何解决模拟Python类的方法和属性的子集

我正在使用mock python模块执行测试。

有时候我在模拟一个类,但是我只想模拟它的一些方法属性,而不是全部。

假设以下情况:

# module.py
class SomeClass:
    def some_method(self):
        return 100

    def another_method(self):
        return 500

# test.py
class Tests(unittest.TestCase):
    @patch('module.someClass')
    def test_some_operation(self,some_class_mock):
        some_class_instance = some_class_mock.return_value

        # I'm mocking only the some_method method.
        some_class_instance.some_method.return_value = 25

        # This is ok,the specific method I mocked returns the value I wished.
        self.assertEquals(
            25,SomeClass().some_method()
        )

        # However,another_method,which I didn't mock,returns a Magicmock instance
        # instead of the original value 500
        self.assertEquals(
            500,SomeClass().another_method()
        )

在上面的代码中,我修补了SomeClass类后,将调用其return_values 我没有明确设置将返回Magicmock个对象。

我的问题是:我该如何仅模拟某些类方法而又不影响其他类?

我可以想到两种方法,但是没有一种是真的好。

  1. 一种方法是将模拟方法设置为原始类方法,如下所示:

    some_class_instance.another_method = SomeClass.another_method
    

    这并不是真正希望的,因为该类可能具有很多方法属性来 “取消模拟”。

  2. 另一种方法是显式修补我想要的每个方法,例如:

     @patch('module.someClass.some_method')
     def test_some_operation(self,some_method_mock):
    

    但是,如果我想模拟类本身,因为它无法模拟对 例如初始化器。无论如何,下面的代码将覆盖所有SomeClass方法

     @patch('module.someClass.some_method')
     @patch('module.someClass')
     def test_some_operation(self,some_class_mock,some_method_mock):
    

这是一个更具体的示例:

class Order:
    def process_event(self,event,data):
        if event == 'event_a':
            return self.process_event_a(data)

        elif event == 'event_b':
            return self.process_event_b(data)

        else:
            return None

    def process_event_a(self,data):
        # do something with data

    def process_event_b(self,data):
        # do something different with data

在这种情况下,我有一个通用方法process_event,它根据所提供的事件来调用特定的处理事件。

我只想测试方法process_event。我只想知道是否根据我提供的事件调用了适当的特定事件。

因此,在我的测试案例中,我想要做的是仅模拟process_event_aprocess_event_b,使用特定参数调用原始的process_event,然后断言{{1} }或process_event_a用适当的参数调用

解决方法

必须修补对象,而不是修补整个类。即,创建您的类的实例,然后修补该实例的方法。

请注意,您也可以使用装饰器class SomeClass: def some_method(self): return 100 def another_method(self): return 500 代替我的方法。

test.py

在您的from unittest import mock class Tests(unittest.TestCase): def test_some_operation(self): some_class_instance = SomeClass() # I'm mocking only the some_method method. with mock.patch.object(some_class_instance,'some_method',return_value=25) as cm: # This is gonna be ok self.assertEquals( 25,SomeClass().some_method() ) # The other methods work as they were supposed to. self.assertEquals( 500,SomeClass().another_method() )

    def create_card_on_the_board_call(self,id_list,card_count,card_name):
    global create_card
    for i in range(card_count):
        create_card = self.rest_api_helper.post_call(
            self.base_url + '/cards?' + 'key=' + test_config[
                'key'] + '&' + 'token=' + test_config[
                'token'] + '&' + f'idList={id_list}' + '&' + f'name={card_name}',headers=None)
    return create_card.json()

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。