如何在pytest单元测试中模拟字典以验证账户函数
解决pytest测试中模拟accounts_dict的问题
要测试validate_account函数中账号是否存在的场景,核心是替换函数所在模块中的accounts_dict变量,而非在测试文件中直接赋值。下面是两种简单有效的实现方式:
方法1:使用pytest自带的monkeypatch fixture
monkeypatch可以临时替换模块级变量,测试结束后自动恢复,避免影响其他用例。假设你的函数在my_module.py中,测试代码如下:
import pytest from my_module import validate_account # 测试账号存在的场景 def test_validate_account_existing(monkeypatch): # 临时替换为包含目标账号的字典 monkeypatch.setattr("my_module.accounts_dict", {1: "测试账号数据"}) assert validate_account("1") == 1 # 测试账号不存在的场景 def test_validate_account_not_existing(monkeypatch): # 替换为不包含目标账号的字典 monkeypatch.setattr("my_module.accounts_dict", {2: "其他账号数据"}) with pytest.raises(Exception) as excinfo: validate_account("1") # 验证抛出的异常信息正确 assert str(excinfo.value) == "Pleaseeee enter a valid account number." # 测试非数字输入的场景 def test_validate_account_non_numeric(): with pytest.raises(ValueError) as excinfo: validate_account("abc") assert str(excinfo.value) == "Please enter a valid account number"
方法2:使用标准库的unittest.mock.patch
通过patch上下文管理器临时替换变量,同样能实现隔离测试:
from unittest.mock import patch from my_module import validate_account import pytest def test_validate_account_existing(): with patch("my_module.accounts_dict", {1: "测试账号数据"}): assert validate_account("1") == 1 def test_validate_account_not_existing(): with patch("my_module.accounts_dict", {}): with pytest.raises(Exception) as excinfo: validate_account("1") assert str(excinfo.value) == "Pleaseeee enter a valid account number."
为什么你之前的方法无效?
你尝试的accounts_dict = Mock(return_value=n)这类方式不对,因为Mock对象默认不支持字典的in判断逻辑(number in accounts_dict会返回False)。直接替换为真实的字典,才能让in操作符按预期工作。
内容的提问来源于stack exchange,提问作者prasgop
相关产品推荐
相关产品推荐

