为了账号安全,请及时绑定邮箱和手机立即绑定

修补在单元测试中在其依赖项中动态生成的数据类属性

修补在单元测试中在其依赖项中动态生成的数据类属性

慕桂英546537 2023-09-05 15:41:18
我是单元测试的新手。我过去使用过模拟、修补,但我的情况对我来说创建单元测试有点复杂。所以我有一个文件:parent.py具有以下数据类import multiprocessingfrom dataclasses import dataclass@dataclassclass ParentClass:    cpu_count: int = multiprocessing.cpu_count() 我有另一个child.py具有以下数据类的模块from stackoverflow.parent import ParentClassfrom dataclasses import dataclass@dataclassclass ChildClass(ParentClass):      some_attribute_1: int = 1      some_attribute_2: int = 2      ....最后,我有第三个actual_function.py使用这些数据类的模块。from stack_overflow.child import ChildClassdef get_cpu_count_and_attributes(cc: ChildClass):    return cc.cpu_count, cc.some_attribute_1 在这里,我想对print_cpu_count_and_attributes功能进行单元测试。这里的补丁是如何工作的?我创建了以下测试用例,但它失败了。我系统中的 cpu_count 是 16,但我想用返回值 8 来模拟它,以便它可以在具有不同核心数量的其他机器上工作from unittest import mockfrom stack_overflow.actual_function import *from stack_overflow.child import ChildClass@mock.patch('stack_overflow.parent.multiprocessing.cpu_count', return_value=8)def test_print_cpu_count_and_attributes():    cc = ChildClass()    assert get_cpu_count_and_attributes(cc) == (8, 1)这是文件夹结构。stackoverflow├── __init__.py  ├── actual_function.py  ├── child.py  ├── parent.py  └── test_function.py
查看完整描述

1 回答

?
慕神8447489

TA贡献1780条经验 获得超1个赞

如果您尝试测试ChildClass,您应该对其进行路径,而不是不同模块中的父级。

带有嘲笑的启发式:

  1. 修补您测试的内容

  2. 尽可能接近目标函数的补丁

你的情况下的补丁不起作用的原因是 python 在补丁之后不会重新评估模块和类层次结构。由于 python 是动态的,所以正在发生的事情是

  1. 家长班级评估

  2. 子类参考父类对象进行评估

  3. 您在父模块中修补父类,但在 中测试代码actual_function,并且ChildClass引用旧的原始Parent,因为mock实际上正在更改命名空间Parent中的对象属性parent.py


您的案例示例:

with mock.patch.object(ChildClass, 'cpu_count', new_callable=mock.PropertyMock) as m:
    m.return_value = 42
    get_cpu_count_and_attributes(ChildClass())

您不应该更改继承的属性/属性,您应该将补丁放在目标之上(因此得名;))


查看完整回答
反对 回复 2023-09-05
  • 1 回答
  • 0 关注
  • 86 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信