【问题标题】:How to mock.patch a class imported in another module如何mock.patch在另一个模块中导入的类
【发布时间】:2015-06-19 19:27:03
【问题描述】:

我有一个带有这样一个模块的 python 类:

xy.py

from a.b import ClassA

class ClassB:
  def method_1():
    a = ClassA()
    a.method2()

然后我将 ClassA 定义为:

b.py

from c import ClassC

class ClassA:
  def method2():
      c = ClassC()
      c.method3()

现在在这段代码中,当为 xy.py 编写测试时,我想 mock.patch ClassC,有没有办法在 python 中实现?

显然我试过了:

mock.patch('a.b.ClassA.ClassC')

mock.patch('a.b.c.ClassC')

这些都不起作用。

【问题讨论】:

    标签: python unit-testing


    【解决方案1】:

    您需要修补ClassC 所在的位置,以便b 中的ClassC

    mock.patch('b.ClassC')
    

    或者,换句话说,ClassC 被导入到模块 b 中,这就是需要修补 ClassC 的范围。

    【讨论】:

    • 假设 b 已被导入。
    • @chepner: mock 会做导入。
    【解决方案2】:

    Where to patch:

    patch() 通过(临时)将名称指向的对象更改为另一个对象。可以有许多名称指向任何单个对象,因此要使修补工作正常,您必须确保修补被测系统使用的名称。

    基本原则是你在查找对象的地方打补丁,这不一定与定义对象的地方相同

    在您的情况下,查找位置是 a.b.ClassC,因为您要修补在 ClassA 中使用的 ClassC

    import mock
    
    with mock.patch('a.b.ClassC') as class_c:
        instance = class_c.return_value  # instance returned by ClassC()
        b = ClassB()
        b.method1()
        assert instance.method3.called == True
        
    

    【讨论】:

    • 请不要只是转储代码,请解释为什么这是一个答案。
    【解决方案3】:

    每次调用ClassA().method2() 方法时,该方法都会将ClassC 查找为全局,从而在a.b 模块中找到ClassC。您需要修补那个位置:

    mock.patch('a.b.ClassC')
    

    请参阅Where to patch section 部分。

    【讨论】:

      猜你喜欢
      • 2019-10-18
      • 1970-01-01
      • 2016-03-28
      • 1970-01-01
      • 1970-01-01
      • 2022-12-10
      • 1970-01-01
      • 2022-01-08
      • 1970-01-01
      相关资源
      最近更新 更多