如何在Python中的对象的模拟方法中调用self?

时间:2013-11-28 03:35:15

标签: python mocking

我尝试测试一些代码,这些代码不返回任何内容,只是将结果保存到数据库中。通过模拟save方法,我希望检查是否已经正确处理了事情:

def mock_save(self):
    assert(self.attr, 'dest_val')
with mock.patch.object(Item, "save", create=True) as save:
    save.side_effect = mock_save
    func_to_call() //in func_to_call, I call item.save()

然而,似乎不允许这样做。它说参数的数量不匹配。

如果我做def mock_save(),它将无效。

我怎样才能引用mock方法所依据的对象呢? (我在另一个适用于 init 方法的线程中看到它,可以直接从类中调用)

2 个答案:

答案 0 :(得分:19)

您需要autospec=True

def mock_save(self):
    assert self.attr == 'dest_val'
with mock.patch.object(Item, "save", autospec=True) as save:
    save.side_effect = mock_save
    func_to_call()

答案 1 :(得分:0)

有时您只想检查方法是否已被调用,但您无法控制其实例化类或调用方法的位置。这种方法可以节省一些时间,无论谁遇到这种模式:

# first get a reference to the original unbound method we want to mock
original_save = Item.save
# then create a wrapper whose main purpose is to record a reference to `self`
# when it will be passed, then delegates the actual work to the unbound method
def side_fx(self, *a, **kw):
    side_fx.self = self
    return original_save(self, *a, **kw)
# you're now ready to play
with patch.object(Item, 'save', autospec=True, side_effect=side_fx) as mock_save:
    data = "the data"
    # your "system under test"
    instance = SomeClass()
    # the method where your mock is used
    instance.some_method(data) 

    # you now want to check if it was indeed called with all the proper arguments
    mock_save.assert_called_once_with(side_fx.self, data)