2013-11-28 81 views
14

我尝试测试一些不返回任何内容但将结果保存到数据库的代码。通过嘲讽的保存方法,我想检查是否东西都被正确处理:如何在Python中用对象的模拟方法调用self?

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(),它将不起作用。

我该如何参考模拟方法所执行的对象呢? (我看到它在另一个线程这是适用于初始化方法,它可以直接从类中调用)

回答

14

你需要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() 
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) 
相关问题