在模拟的导入类上,称为断言的函数失败

时间:2020-04-30 11:34:57

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

我正在尝试在Python 3中测试verifyEmail action › calls completeRegistration function if successful expect(jest.fn()).toBeCalled() Expected number of calls: >= 1 Received number of calls: 0

ClassToTest

该类由其他一些类实现,因此我进行了简单的设置:

from path.to import ClassThatNeedsMocking

class ClassToTest:

  def __init__(self):
    pass

  def setup(self):
    foo = ClassThatNeedsMocking()
    foo.functionCall()

我想用以下内容模拟from some.other.path import ClassToTest class ImplementingClass(ClassToTest): def __init__(self): super().__init__() 中的functionCall

ClassToTest

class TestClass: def testMethod(self): patch = mock.patch('path.to.ClassThatNeedsMocking') patcher = patch.start() patcher = MagicMock() patcher.functionCall = MagicMock() foo = ImplementingClass() foo.setup() # Results in an 'Expected to have been called once. Called 0 times.' patcher.functionCall.assert_called_once() patch.stop() 中打印foo.functionCall()时,它返回一个ClassToTest对象,但是断言仍然失败。这是正确的测试设置吗?我在这里缺少什么?

2 个答案:

答案 0 :(得分:2)

这将起作用:

@mock.patch('path_to_class_to_test.ClassThatNeedsMocking')
def test_method(patched):
    foo = ImplementingClass()
    foo.setup()
    patched.return_value.functionCall.assert_called_once()

首先,您需要在该类中修补已导入的类 进行测试(请参见where to patch)。如果使用import from,则将该类分配给一个新对象,该对象位于using模块中,这是必须修补的对象。

第二,您只需要修补的类-不需要其他模拟程序,也无需启动/停止修补程序。您可以使用装饰器(如我所做的那样)或函数调用来获取它。超出功能范围后,将立即还原补丁。

第三,您修补了该类,但是该函数由类 instance 调用,该类为patched.return_value,因此必须进行检查。

答案 1 :(得分:0)

使用MrBean Bremen's答案的最终测试更为简洁。为了完整起见,示例中的错误位于以下位置:

class TestClass:

  def testMethod(self):
    patch = mock.patch('path.to.ClassThatNeedsMocking')

    patcher = patch.start()
    #####################
    patcher = MagicMock()
    patcher.functionCall = MagicMock()
    #####################

    foo = ImplementingClass()
    foo.setup()

    patcher.functionCall.assert_called_once()

    patch.stop()

patch.start()调用的返回值应直接用于对以下内容进行断言:

class TestClass:

  def testMethod(self):
    patch = mock.patch('path.to.ClassThatNeedsMocking')

    patcher = patch.start()

    foo = ImplementingClass()
    foo.setup()

    patcher.return_value.functionCall.assert_called_once()

    patch.stop()