Mocking/patching 一个对象属性来测试一个方法

Mocking/patching an object attribute to test a method

我正在使用 pytest 测试我的代码,并试图找出最直接的方法来测试我的 class' 方法之一。

我有一个class喜欢:

class MyClass():
    def __init__(self, stuff):
     ...
    ..
    ..
    def _method_of_interest(self, list1, list2):
        
        ..some logic that depends on list1, list2, and self.relevant_info
  
        return output 

我想测试方法 _method_of_interest 作为某些 list1、list2 和 self.relevant_info 组合的函数。我宁愿不必实例化 MyClass 的真实对象,因为在逻辑链的其他地方有一些耗时的计算而且我不能轻易地创建具有我想要的 self.relevant_info 值的全部范围的对象测试。

使用不同的 list1、list2 和 self.relevant_info 值测试此方法输出的最简洁方法是什么?

为了具体起见,我们可以假设 _method_of_interest 是这样的:

def _method_of_interest(list1, list2):
    return list1 + list2 + list(self.relevant_info)

其中 self.relevant_info 是一个 python set() 对象。

有什么指点吗?网上有很多关于模拟、修补等的内容,但这些示例看起来都比我的情况复杂,而且解决问题的方法多种多样,这让我不确定哪种方法最干净。

如果你想测试一个与 class 的其余部分完全隔离的方法,你总是可以通过 mock self:

# code under test
class MyClass():
    def __init__(self):
        raise NotImplementedError  # don't instantiate me!

    def _method_of_interest(self, list1, list2):
        return list1 + list2 + list(self.relevant_info)


# test
from unittest.mock import Mock

def test_method_of_interest():
    assert MyClass._method_of_interest(
        Mock(relevant_info=[3]), [1], [2]
    ) == [1, 2, 3]

如果您 运行 测试,您会看到它通过了,并且 MyClass 永远不会被实例化。