Python模拟访问"真实"模拟模块时的对象

时间:2015-05-29 17:15:00

标签: python mocking python-mock

是否可以访问"真实"模拟模块时的对象?我试图做的是模拟一些功能,但抛出真实的"例外,像这样:

@mock.patch('my_project.requests')
def test_foo(self,  mock_requests):

    mock_requests.post = mock.Mock(side_effect=requests.ConnectionError())

    thread = CommandThread("command", 3, 2, 0)
    thread.run() #this is were I exercise requests.post

    self.assert(thread.was_successful is False)

在我的CommandThread内部,我有一张支票

try:
    requests.post(url, data=data)
except (requests.ConnectionError, requests.Timeout):
    self.was_successful = False

但是,我的测试失败了,因为异常没有在try / except块中捕获(当我喜欢它except Exception:时它工作) 我认为,原因仅仅是因为我嘲笑了这个"命名空间"在我的测试用例中,我实际上从原始包中提出my_project.requests.ConnectionError异常,而不是正确的requests.ConnectionError。 是否有可能访问/抛出真实的"异常?

1 个答案:

答案 0 :(得分:1)

这种情况正在发生,因为您的模拟实际上正在覆盖代码中的整个请求模块。以下是调试方法:

在您的代码中,添加以下内容:

try:
    requests.post('', data='')
except (requests.ConnectionError, requests.Timeout):
    was_successful = False
except Exception, err:
    import pdb
    pdb.set_trace()

当您运行测试时,您将被放入调试器中,以便您可以查看正在发生的事情。如果我们看看你正在捕捉什么,这就是我们所看到的:

(Pdb) requests.ConnectionError
<MagicMock name='requests.ConnectionError' id='4562438992'>

你实际上是在捕捉一个模拟的ConnectionError,因为你的模拟修补了整个请求模块而你正在提出一个真正的请求错误。

您可以通过使模拟更具体并且仅覆盖请求模块上的post方法来解决此问题:

@mock.patch('my_project.requests.post')
def test_foo(self,  mock_requests):
    mock_requests.side_effect = requests.ConnectionError()
    ...