首页 > 解决方案 > Pytest 模拟 AWS SecurityManager

问题描述

我的项目有一个名为 config.py 的文件,其中包含以下代码:

class Secret(Enum):
    DATABASE_A = 'name_of_secret_database_A'
    DATABASE_A = 'name_of_secret_database_A'

    def secret(self):
        if self.value:
            return get_secret(self.value)
        return {}

def get_secret(secret_name):
    session = Session()
    client = session.client(
        service_name='secretsmanager',
        region_name='us-east-1',
    )
    secret_value = client.get_secret_value(SecretId=secret_name)
    return loads(secret_value.get('SecretString', "{}"))

我需要以某种方式在所有枚举调用的pytest 测试中模拟 get_secret,例如Secret.DATABASE_A.secret ()

标签: pythonmockingpytestaws-secrets-manager

解决方案


您可以使用monkeypatch来覆盖get_secret(). 我已经将该get_secret()方法设为 Secret 类的静态方法,但您可以将其作为您想要的任何模块的一部分并导入它。只需确保您在monkeypatch.setattr()通话中也进行了更改。

import pytest
from enum import Enum


class Secret(Enum):
    DATABASE_A = 'name_of_secret_database_A'
    DATABASE_B = 'name_of_secret_database_B'

    def secret(self):
        if self.value:
            return Secret.get_secret(self.value)
        return {}
        
    @staticmethod
    def get_secret(secret_name):
        session = Session()
        client = session.client(
            service_name='secretsmanager',
            region_name='us-east-1',
        )
        secret_value = client.get_secret_value(SecretId=secret_name)
        return loads(secret_value.get('SecretString', "{}"))

def test_secret_method(monkeypatch):
    def get_secret(secret_name):
        return "supersecret"
    
    monkeypatch.setattr(Secret, "get_secret", get_secret)

    s = Secret.DATABASE_A
    assert s.secret() == "supersecret"

这将返回 1 个通过的测试。

这里发生的是,我get_secret()也在我的 test_secret_method 中创建了一个函数,然后Secret.get_secret()用那个新方法覆盖了。现在,您可以在 test_method 中使用 Secret 类,并确定“get_secret()”方法将返回什么,而无需实际运行原始代码。


推荐阅读