如何在 python 中正确模拟 gcp 客户端库调用
How to correctly mock a gcp client library call in python
如何为使用 GCP 秘密管理器客户端库的函数正确编写单元测试。我一直在阅读单元测试和模拟,但我似乎无法理解这里出了什么问题。除了非常基本的单元测试之外,我从来没有真正编写过单元测试,也没有做过模拟。我在文件 main.py
中有以下 get_secret
函数,returns 一个字符串。
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
文件,我在其中尝试模拟 secretmanager。
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
类型的对象有关,它有一个 payload
类型的 google.cloud.secretmanager_v1.types.SecretPayload
对象,它是一个 data
类型的对象 bytes
任何有关如何正确执行此操作的帮助将不胜感激。
@patch("main.secretmanager")
尝试修补 secretmanager
这是一个模块,但我需要修补 secretmanager.SecretManagerServiceClient
这是一个 class,我试过这个但它是由于我在 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'
如何为使用 GCP 秘密管理器客户端库的函数正确编写单元测试。我一直在阅读单元测试和模拟,但我似乎无法理解这里出了什么问题。除了非常基本的单元测试之外,我从来没有真正编写过单元测试,也没有做过模拟。我在文件 main.py
中有以下 get_secret
函数,returns 一个字符串。
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
文件,我在其中尝试模拟 secretmanager。
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
类型的对象有关,它有一个 payload
类型的 google.cloud.secretmanager_v1.types.SecretPayload
对象,它是一个 data
类型的对象 bytes
任何有关如何正确执行此操作的帮助将不胜感激。
@patch("main.secretmanager")
尝试修补 secretmanager
这是一个模块,但我需要修补 secretmanager.SecretManagerServiceClient
这是一个 class,我试过这个但它是由于我在 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'