【问题标题】:How to mock a class in an instance attribute using patch如何使用补丁模拟实例属性中的类
【发布时间】:2017-07-14 17:16:39
【问题描述】:

我对 python 还很陌生,目前正在尝试为一个类编写单元测试,但是在模拟依赖项时遇到了一些问题。我有 2 个类,其中一个 (ClassB) 是另一个 (ClassC) 的依赖项。目标是在 ClassC 的测试用例中模拟 ClassB 和 ArgumentParser 类。 ClassB 如下所示:

# defined in a.b.b
class ClassB:
    def doStuff(self) -> None:
        # do stuff
        pass

    def doSomethingElse(self) -> None:
        # do something else
        pass

C类:

# defined in a.b.c
from .b import ClassB
from argparse import ArgumentParser

class ClassC:

    b

    def __init__(self) -> None:
        arguments = self.parseArguments()
        self.b = ClassB()
        self.b.doStuff()

    def close(self) -> None:
        self.b.doSomethingElse()

    def parseArguments(self) -> dict:
        c = ArgumentParser()
        return return parser.parse_args()

最后是 ClassC 的测试用例:

# inside a.b.test
from unittest import TestCase
from unittest.mock import patch, MagicMock
from a.b.c import ClassC

class ClassCTest(TestCase):
    @patch('a.b.c.ClassB')
    @patch('a.b.c.ArgumentParser')
    def test__init__(self, mock_ArgumentParser, mock_ClassB):
        c = ClassC()
        print(isinstance(c.b, MagicMock))           # outputs False
        # for reference
        print(isinstance(mock_ClassB, MagicMock))   # outputs True

我在补丁docs 中读到,在它使用的命名空间中模拟类很重要,而不是在它定义的地方。所以这就是我所做的,我嘲笑道:a.b.c.classB 而不是 a.b.b.classB,尽管两者都试过了。我也尝试在 test__init__ 方法体中导入 ClassC,但这也没有用。 我更喜欢不模拟 ClassB 的方法,而是模拟整个类,以使测试尽可能隔离。

环境信息: Python 3.6.1

任何帮助将不胜感激!

【问题讨论】:

  • 你的测试中print(c.b)是什么对象?是ClassB 的实例吗?
  • 它没有,但你的问题让我意识到我有一个与实例属性同名的类属性!现已修复

标签: python python-3.x unit-testing


【解决方案1】:

由于我是 python 新手,所以我不知道 class attributes。我在 ClassC 中有一个包含 ClassB 的类属性,在 init 中有一个隐藏类属性的实例属性。

【讨论】:

    猜你喜欢
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-18
    • 1970-01-01
    • 2016-04-27
    • 2021-08-21
    • 1970-01-01
    相关资源
    最近更新 更多