Python,Mock:抛出异常

65

我在测试中遇到一个从函数中引发异常的问题:

### Implemetation
def MethodToTest():
    myVar = StdObject()
    try:
        myVar.raiseError() # <--- here
        return True
    except Exception as e:
        # ... code to test
        return False

### Test file
@patch('stdLib.StdObject', autospec=True)
def test_MethodeToTest(self, mockedObjectConstructor):
    mockedObj = mockedObjectConstructor.return_value
    mockedObj.raiseError.side_effect = Exception('Test') # <--- do not work
    ret = MethodToTest()
    assert ret is False

我希望使用raiseError()函数来引发错误。

我在SO上找到了几个示例,但没有符合我的需求。


也许这个链接可以帮助你:https://dev59.com/qnI-5IYBdhLWcg3wBjdR - Alex L
1
你确定你正在正确的位置打补丁(在导入它的地方,而不是从哪里导入)吗? - jonrsharpe
我认为我已经在正确的位置打了补丁,因为我的其他测试都按预期工作。 - user4780495
side_effect() 支持抛出异常。可能您打了错误的补丁对象。 - guettli
2个回答

79

我改变了

@patch('stdLib.StdObject', autospec=True)
@patch('stdLib.StdObject', **{'return_value.raiseError.side_effect': Exception()})

并删除了# <--- do not work这行代码。

现在它正在运行。

这个链接是一个很好的例子。

编辑:

mockedObj.raiseError.side_effect = Mock(side_effect=Exception('Test'))

同样有效。


26
这个对我起作用:mockedObj.side_effect = Exception('测试') - Hai Nguyen
14
@patchзҡ„еҸӮж•°дјҡдј йҖ’з»ҷMockзҡ„жһ„йҖ еҮҪж•°пјҢжүҖд»ҘдҪҝз”Ё@patch('stdLib.StdObject', side_effect=Exception('Test'))д№ҹеҸҜд»Ҙ并且жӣҙзҹӯгҖӮ - luto
2
@luto的评论对我很有帮助。修补mockedObj.raiseError.side_effect并没有真正地引发错误。 - verboze

18

好的,您提供的答案是有效的,但是您改变了解决问题的方式(这是可以接受的)。为了修复您最初的问题,您需要将一个函数分配给side_effect,而不是结果或对象:

def my_side_effect():
    raise Exception("Test")

@patch('stdLib.StdObject', autospec=True)
def test_MethodeToTest(self, mockedObjectConstructor):
    mockedObj = mockedObjectConstructor.return_value
    mockedObj.raiseError.side_effect = my_side_effect # <- note no brackets, 
    ret = MethodToTest()
    assert ret is False

希望能对您有所帮助。请注意,如果目标方法接受参数,则副作用也需要接受相应的参数(我认为)。


13
你不需要指定一个函数;那只是其中一种选项,但在这里并不是最好的选择。直接将异常赋值给 side_effect 即可:mockedObj.raiseError.side_effect = Exception("Test") - Martijn Pieters
1
你不必担心:他的编辑有第三种方法,即使用设置了副作用的 Mock 进行模拟,但这仍然是一种有效且好的测试方法。这样做没有任何问题,特别是它让你以后可以扩展你的测试。 - Jmons
1
OP编辑了他们的问题吗?看起来他们已经分配给side_effect,而@MartijnPieters的建议看起来正好像他们评论中写的那行代码“不起作用”。 - Davos
我认为这个问题没有被编辑过。我认为在当时(考虑到这是2016年11月,现在已经是2018年11月),我对side_effect的理解是它被作为一个函数调用——这是不正确的,你应该能够做像side_effect = 12这样的事情。鉴于OP给出了一个完全不同的答案,然后接受了它,我想知道是否有其他未粘贴的代码错误。如果我记得正确,我把这段代码复制到一个shell脚本中进行了测试,也看到它在使用函数之前“无法工作”。但那是两年前的事了!现在我是一个更好的Python程序员。 - Jmons

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接