ton*_*oft 5 python unit-testing mocking python-mock
是否可以在继续使用同名其他字段/函数的生产版本的同时模拟 python 构造函数?例如,给定生产代码:
class MyClass:
class SubClass:
def __init__(self) -> None:
print("\nreal sub init called")
class SubSubClass:
def __init__(self) -> None:
print("\nreal sub sub init called")
Run Code Online (Sandbox Code Playgroud)
以及以下测试代码:
class FakeSubClass:
def __init__(self) -> None:
print("\nfake init called")
def test():
MyClass.SubClass()
MyClass.SubClass.SubSubClass()
MyClass.SubClass = Mock(side_effect=FakeSubClass)
MyClass.SubClass()
MyClass.SubClass.SubSubClass()
Run Code Online (Sandbox Code Playgroud)
我们得到以下输出:
real sub init called
real sub sub init called
fake init called
Run Code Online (Sandbox Code Playgroud)
请注意,最后一行MyClass.SubClass.SubSubClass()没有创建真正的 SubSubClass,因为此时它是 SubClass 模拟的自动创建的属性。
我想要的输出如下:
real sub init called
real sub sub init called
fake init called
real sub sub init called
Run Code Online (Sandbox Code Playgroud)
换句话说,我只想模拟子类,而不是子子类。我已经尝试过代替上面的嘲笑线的事情(两者都不起作用):
MyClass.SubClass.__init__ = Mock(side_effect=FakeSubClass.__init__)
MyClass.SubClass.__new__ = Mock(side_effect=FakeSubClass.__new__)
Run Code Online (Sandbox Code Playgroud)
请注意,我知道可以通过多种方式重构代码以避免此问题,但遗憾的是代码无法重构。
您也可以伪造该类,MyClass.SubClass.SubSubClass()在您的情况下不起作用的是MyClass.SubClass模拟没有SubSubClass定义。只需让其FakeSubClass从 MyClass.SubClass 继承即可解决问题。
您可以轻松地修补MyClass到FakeClass,并且您将拥有正确的测试对象而不是真实对象。
from unittest.mock import Mock
class MyClass:
class SubClass:
def __init__(self) -> None:
print("\nreal sub init called")
class SubSubClass:
def __init__(self) -> None:
print("\nreal sub sub init called")
class FakeSubClass(MyClass.SubClass, Mock):
def __init__(self) -> None:
print("\nfake init called")
class FakeClass:
class SubClass(FakeSubClass):
pass
def test():
MyClass.SubClass()
MyClass.SubClass.SubSubClass()
MyClass.SubClass = Mock(side_effect=FakeSubClass)
FakeClass.SubClass()
FakeClass.SubClass.SubSubClass()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2947 次 |
| 最近记录: |