为什么在模块范围内实例化的模拟类说它没有实例化?



我有一个SlackClient类,我在模块范围内的主程序main.py中实例化,在整个模块中重用(有点像单例),通过Slack发送消息。但是,我无法获得模拟客户端的测试工作(我不希望客户端每次运行单元测试时都向Slack发送消息),并测试客户端是否使用正确的验证令牌实例化。

Slack客户端:

## slack_client.py
class SlackClient:
def __init__(self, auth_token):
pass
def instantiate_client():
get_token_from_secrets = lambda: "mock-auth-token"
return SlackClient(get_token_from_secrets())

客户端实例化和使用的主程序:

## main.py
from slack import instantiate_client
slack_client = instantiate_client()
# Then in this file I do some logic that calls the slack_client singleton.

我测试参数SlackClient()的测试文件被实例化为:

import core
from unittest.mock import MagicMock, patch
@patch("core.slack_client")
def test_instantiation(slack_client):
# This should succeed, but it fails
slack_client.assert_called_once_with("mock-auth-token")
test_instantiation()

如何在模块范围内测试用于实例化类的参数?

我假设你有一些项目结构看起来像这样:

project
|_ core
|  |_ __init__.py
|  |_ slack_client.py
|_ main.py
|_ test.py

如果是这样,当您应该修补core.slack_client.SlackClient类时,您正在修补整个core.slack_client模块。

测试文件应该是这样的:

from unittest.mock import MagicMock, patch
# patch the object with this namespace
@patch("core.slack_client.SlackClient")
def test_instantiation(slack_client):
slack_client.assert_called_once_with("mock-auth-token")
test_instantiation()

如果这有效,您根本不需要像mock一样导入core。Patch将负责修补该名称空间。或者,如果我对你的项目结构错了,你可能需要使用mock.patch.object而不是mock.patch:

import core
from unittest.mock import MagicMock, patch
# patch the "SlackClient" object in the "core" module
@patch(core, "SlackClient")
def test_instantiation(slack_client):
slack_client.assert_called_once_with("mock-auth-token")
test_instantiation()

最新更新