如何Mock Fernet.decrypt以实现Python脚本测试覆盖?
解决Fernet解密测试时的Mock问题
核心问题
测试时无法获取环境变量中的解密短语,导致Fernet解密抛出InvalidToken错误,需要Mock Fernet的解密逻辑,跳过真实的密钥验证步骤。
解决方案:使用unittest.mock.patch Mock Fernet
方法1:Mock Fernet类及实例的decrypt方法
假设你的业务代码在your_module.py中:
from cryptography.fernet import Fernet PATH = "some/path/to/key" class KeyHandler: def __init__(self, decrypt_phrase): self.decrypt_phrase = decrypt_phrase def decrypt_and_save(self, encrypted_data): f = Fernet(self.decrypt_phrase) decrypted_data = f.decrypt(encrypted_data) with open(PATH, "wb") as file: file.write(decrypted_data) return decrypted_data
测试代码(以pytest为例):
from unittest.mock import patch, MagicMock from your_module import KeyHandler def test_decrypt_and_save(): # 1. 预设模拟的解密结果 mock_decrypted = b"valid_jwt_secret_key" # 2. 创建Fernet实例的Mock对象,指定decrypt方法返回预设值 mock_fernet = MagicMock() mock_fernet.decrypt.return_value = mock_decrypted # 3. Patch业务代码中使用的Fernet类(关键:patch路径是业务模块中的Fernet引用) with patch("your_module.Fernet", return_value=mock_fernet): # 初始化Handler,解密短语随便填(不会被真实使用) handler = KeyHandler(decrypt_phrase=b"fake_phrase") # 调用测试方法 result = handler.decrypt_and_save(b"fake_encrypted_data") # 验证调用逻辑是否符合预期 mock_fernet.decrypt.assert_called_once_with(b"fake_encrypted_data") assert result == mock_decrypted
关键注意点
- Patch路径要正确:必须patch业务代码中实际导入使用的
Fernet,即your_module.Fernet,而非cryptography.fernet.Fernet。因为patch是替换被测试代码中引用的对象,而非原模块的对象。 - 隔离文件写入:如果不想测试时真实写入文件,可以额外Mock
builtins.open:with patch("your_module.Fernet", return_value=mock_fernet), \ patch("builtins.open", MagicMock()) as mock_open: handler.decrypt_and_save(b"fake_encrypted_data") # 验证文件操作 mock_open.assert_called_once_with("some/path/to/key", "wb") mock_open.return_value.__enter__.return_value.write.assert_called_once_with(mock_decrypted)
备选方案:在tox中设置测试用环境变量
如果不想Mock,也可以在tox.ini中直接设置测试用的解密短语,避免环境变量缺失:
[testenv] # 传递系统环境变量(如果本地有设置) passenv = DECRYPT_PHRASE # 或者直接设置测试用密钥(需提前生成一个Fernet密钥) setenv = DECRYPT_PHRASE = gAAAAABk...(你的测试用Fernet密钥)
这种方式会走真实的解密逻辑,适合需要验证解密流程正确性的场景,但灵活性不如Mock。
内容的提问来源于stack exchange,提问作者user130667
相关产品推荐
相关产品推荐

