如何在python中正确模拟gcp客户端库调用



如何正确地为使用GCP秘密管理器客户端库的函数编写单元测试?我一直在阅读单元测试和mock,但我似乎无法理解这里出了什么问题。除了非常基本的单元测试之外,我从来没有真正写过单元测试,也没有写过mock。我在文件main.py中有以下get_secret函数,它返回一个字符串。

from google.cloud import secretmanager
def get_secret(project_id,secret_name) -> str:
"""
Get secret from gcp secrets manager
"""
client = secretmanager.SecretManagerServiceClient()
request = {"name": f"projects/{project_id}/secrets/{secret_name}/versions/latest"}
response = client.access_secret_version(request)
secret_string = response.payload.data.decode("UTF-8")
return secret_string

我有以下test_main.py文件,我试图嘲笑秘书经理。

import pytest
from unittest.mock import patch
from main import get_secret
@pytest.fixture()
def secret_string():
return 'super_secret_token'
@patch("main.secretmanager") # mock secretmanager from main.py
def test_get_secret(secretmanager,secret_string):
secretmanager.SecretManagerServiceClient().access_secret_version().return_value = secret_string
secret_string = get_secret('project_id','secret_name')
assert secret_string == 'super_secret_token'

当我运行pytest时,AssertionError: assert <MagicMock name='secretmanager.SecretManagerServiceClient().access_secret_version().payload.data.decode()' id='4409262192'> == 'super_secret_token'测试失败

我知道为什么,但我不完全确定。我想这是关于access_secret_version()返回一个类型为google.cloud.secretmanager_v1.types.service.AccessSecretVersionResponse的对象它有一个类型为google.cloud.secretmanager_v1.types.SecretPayloadpayload对象它是一个类型为bytesdata对象

任何关于如何正确地做到这一点的帮助将不胜感激。

@patch("main.secretmanager")试图修补secretmanager,这是一个模块,但我需要修补secretmanager.SecretManagerServiceClient,这是一个类,我曾尝试过,但它给了我错误,由于我使用的语法不正确的return_value。

@patch("main.secretmanager.SecretManagerServiceClient")
def test_get_secret(self, mock_smc):
mock_smc.return_value.access_secret_version.return_value.payload.data = b'super_secret_token'
secret_string = get_secret('project_id', 'secret_name')
assert secret_string == 'super_secret_token'

你也可以给access_secret_version()打补丁,但是在运行测试时,当client = secretmanager.SecretManagerServiceClient()被调用时,它会尝试用gcp进行身份验证,如果没有有效的凭据,它将失败。在运行单元测试时,最好不要使用外部服务进行身份验证。

from unittest.mock import patch
from main import get_secret
@patch("main.secretmanager.SecretManagerServiceClient.access_secret_version")
def test_get_secret(secretmanager):
secretmanager.return_value.payload.data = b'super_secret_token'
secret_string = get_secret('project_id', 'secret_name')
assert secret_string == 'super_secret_token'

相关内容

  • 没有找到相关文章

最新更新