Python 模拟对象的多个实例

Python 模拟对象的多个实例,python,unit-testing,mocking,Python,Unit Testing,Mocking,我正在寻找一种方法来模拟同一类的多个实例。尝试了来自的解决方案,但确实有效。但是,我还想为测试用例中模拟类的每个新实例指定属性和行为。我还没找到答案 例如: class A: def __init__(self, name): self.name = name def get_name(self): print("hi " + self.name) return self.name class B: def __ini

我正在寻找一种方法来模拟同一类的多个实例。尝试了来自的解决方案,但确实有效。但是,我还想为测试用例中模拟类的每个新实例指定属性和行为。我还没找到答案

例如:

class A:
    def __init__(self, name):
        self.name = name

    def get_name(self):
        print("hi " + self.name)
        return self.name


class B:
    def __init__(self):
        self.a_map = {}

    def get_all_a_values(self, names):
        for name in names:
            a = A(name)
            self.a_map[a] = a.get_name()


with mock.patch('__main__.A') as mockA:
    b = B()
    mockA.side_effect = mock.Mock
    names = ['person0', 'person1', 'person2', 'person3', 'person4']
    b.get_all_a_values(names)
    print(b.a_map)
    assert len(b.a_map) == 5
如何更改此代码,以便在创建mockA实例时,它还设置实例的name属性?e、 g.我需要此代码的输出类似于:

{<Mock id='13609360'>: 'person0', <Mock id='13608720'>: 'person1', <Mock id='13610128'>: 'person2', <Mock id='13609744'>: 'person3', <Mock id='13608976'>: 'person4'}
{:‘person0’、:‘person1’、:‘person2’、:‘person3’、:‘person4’}

设置mockA.get\u name.return\u值将不起作用,因为它将对每个实例使用相同的值。

请注意,名称是由A的
get\u name
方法返回的。因此,您可以使用一个副作用覆盖该方法,该副作用返回调用该方法的名称。看起来您真正想要的不是多个mock实例,而是mock中的一个方法,它根据传递给它的内容返回不同的值

以下代码适用于我:

import mock

class A:
    def __init__(self, name):
        self.name = name

    def get_name(self):
        print("hi " + self.name)
        return self.name


class B:
    def __init__(self):
        self.a_map = {}

    def get_all_a_values(self, names):
        for name in names:
            a = A(name)
            self.a_map[a] = a.get_name()


def side_effect(name):
    mm = mock.MagicMock()
    mm.get_name.return_value = name
    return mm

with mock.patch('__main__.A') as mockA:
    b = B()
    mockA.side_effect = side_effect
    names = ['person0', 'person1', 'person2', 'person3', 'person4']
    b.get_all_a_values(names)
    print(b.a_map)
    assert len(b.a_map) == 5
运行此操作时,我的输出为:

{<MagicMock id='4491688656'>: 'person0', <MagicMock id='4491693264'>: 'person1', <MagicMock id='4491757456'>: 'person4', <MagicMock id='4491722960'>: 'person2', <MagicMock id='4491742224'>: 'person3'}
{:‘person0’、:‘person1’、:‘person4’、:‘person2’、:‘person3’}

我发现mock文档相对来说比较混乱,但是关于的部分值得一试,因为它们是mock中最有用的特性之一

尝试你的例子,它的工作。。。而且也有道理。。感谢您提供了令人困惑的文档。我已经经历过了。我一直认为副作用函数示例仅适用于函数模块。让我觉得作者不希望我们在可以避免的情况下使用类和OO。我发现,他们的例子更多的是展示它的工作原理,而不是展示如何使用它。它真的,真的是多才多艺,几乎可以做任何你想做的事情,但弄清楚如何经常是一个挑战。