python - 可以在不模拟对象的其他属性的情况下模拟 python 构造函数吗?

标签 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")

和下面的测试代码:

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()

我们得到以下输出:

real sub init called

real sub sub init called

fake init called

请注意,最后一行 MyClass.SubClass.SubSubClass() 并未创建真正的 SubSubClass,因为此时它是 SubClass mock 的自动创建属性。

我想要的输出如下:

real sub init called

real sub sub init called

fake init called

real sub sub init called

换句话说,我只想模拟 SubClass,而不是 SubSubClass。我已经尝试代替上面的模拟行的东西(两者都不起作用):

MyClass.SubClass.__init__ = Mock(side_effect=FakeSubClass.__init__)

MyClass.SubClass.__new__ = Mock(side_effect=FakeSubClass.__new__)

请注意,我知道有几种重构代码的方法可以避免此问题,但遗憾的是代码无法重构。

最佳答案

你也可以伪造类,MyClass.SubClass.SubSubClass() 在你的情况下不起作用是因为 MyClass.SubClass 是一个 Mock 没有 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()

关于python - 可以在不模拟对象的其他属性的情况下模拟 python 构造函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51063324/

相关文章:

python - 使用二元分类器模型将数据分为 3 类

python - 延迟加载模块导入 __init__.py 文件 python

c# - C# 代码的单元测试,其中主要处理发生在 SQL 存储过程中

python - 循环中的 Scrapy 调用请求

python matplotlib : mark dots over Line2D

java - 需要 JUnit 测试方面的帮助

c# - MSTest.exe 给出程序集或模块未找到警告

python - 如何模拟类并使用 pytest-mock 控制 py.test 中的返回值?

entity-framework-4 - 如何 EF4 + Ninject + 起订量?

python - 模拟函数默认使用装饰器