You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python Mock:如何允许字典属性取指定列表中的特定值?

实现字典属性的枚举值断言方案

我来给你几个实用的办法,帮你实现这个需求——确保测试中的city字段只能取指定的两个值,同时还能复用那个被大量用例依赖的共享常量字典:

方法一:直接拆分断言(简单直接)

既然共享常量里的city只是占位,我们可以在测试里单独对city做范围断言,其他固定字段直接用相等断言:

def test_something(self):
    result = something.query("something")
    actual_geoip = result[0]["data"]["geoip"]
    
    # 先验证固定值字段(比如country)
    self.assertEqual(actual_geoip["country"], expected_geoip["country"])
    # 单独验证city必须是指定值之一
    self.assertIn(actual_geoip["city"], ["Helsinki", "Espoo"],
                  msg=f"City 只能是 Helsinki 或 Espoo,实际得到: {actual_geoip['city']}")

这种方式的好处是不需要修改共享常量,不会影响其他依赖这个常量的测试用例,代码也直观易懂,适合字段规则简单的场景。

方法二:优化常量定义+自定义断言函数(维护友好)

如果想把city的允许值规则也统一放在常量文件里,方便后续维护,可以修改常量的结构,再写个通用的断言函数:

第一步:修改共享常量文件

expected_geoip = { 
    "country": "Finland", 
    # 把city改成存储允许值的结构
    "city": {"allowed_values": ["Helsinki", "Espoo"]}
}

第二步:写通用断言函数(可以放在测试基类或辅助模块)

def assert_geoip_valid(self, actual_geoip):
    # 验证固定值字段
    self.assertEqual(actual_geoip["country"], expected_geoip["country"])
    
    # 验证city的取值范围
    allowed_cities = expected_geoip["city"]["allowed_values"]
    self.assertIn(actual_geoip["city"], allowed_cities,
                  msg=f"City 必须是 {allowed_cities} 之一,实际得到: {actual_geoip['city']}")

第三步:在测试用例中调用

def test_something(self):
    result = something.query("something")
    actual_geoip = result[0]["data"]["geoip"]
    self.assert_geoip_valid(actual_geoip)

这种方式的优势是规则集中管理,所有测试用例都用同一个断言函数,后续如果要修改允许的城市列表,只需要改常量文件就行,不用逐个修改测试用例。

方法三:用subTest做批量字段验证(扩展性强)

如果后续有更多字段需要类似的枚举值规则,可以用unittestsubTest来批量验证,这样一次就能找出所有不符合规则的字段:

def test_something(self):
    result = something.query("something")
    actual_geoip = result[0]["data"]["geoip"]
    
    # 定义所有字段的验证规则:固定值用字符串,枚举值用列表
    field_validation_rules = {
        "country": expected_geoip["country"],
        "city": ["Helsinki", "Espoo"]
    }
    
    for field, rule in field_validation_rules.items():
        with self.subTest(field=field):
            if isinstance(rule, list):
                # 枚举值规则:断言实际值在列表中
                self.assertIn(actual_geoip[field], rule)
            else:
                # 固定值规则:断言相等
                self.assertEqual(actual_geoip[field], rule)

这种方式的好处是扩展性极佳,新增字段规则只需要在field_validation_rules里加一行就行,而且subTest会把所有不匹配的字段都报告出来,不用反复运行测试排查问题。

内容的提问来源于stack exchange,提问作者Juha Untinen

火山引擎 最新活动