【问题标题】:Python mock access "real" objects while mocking a modulePython 在模拟模块时模拟访问“真实”对象
【发布时间】:2015-08-12 15:56:54
【问题描述】:

是否可以在模拟模块时访问“真实”对象?我正在尝试做的是模拟一些功能,但抛出“真正的”异常,如下所示:

@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。 是否有可能访问/抛出“真正的”异常?

【问题讨论】:

    标签: python mocking python-mock


    【解决方案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()
        ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多