我有一个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()