如何测试对象的方法是否被调用?

问题描述 投票:0回答:2

嗨,我正在尝试测试对象 A 中的方法是否调用另一个对象(对象 B)的方法。我已经有单独的测试来测试 B 的功能,因此我的目标只是查看 B 的方法是否已被调用。我尝试使用模拟创建模拟对象 B,遵循类似于 this 的方法,但不断收到以下错误:

AssertionError: Expected 'process' to have been called once. Called 0 times.
我是否做错了模拟?

根据我的理解,这个answer建议访问 sut 中的字段并将其设置为模拟,但由于我的代码设置方式,我无法访问其他对象。

示例代码:

# object B
from abc import ABCMeta


class B(metaclass=ABCMeta):
    def process(self):
        print('I am B')
# object C
from abc import ABCMeta


class C(metaclass=ABCMeta):
    def process(self):
        print('I am C')
# object A
from abc import ABCMeta

from b import B
from c import C


class A(metaclass=ABCMeta):
    def __init__(self):
        self.__known_auto_processes = {}
        self.__inti_know_processes()

    def process(self, arg):
        try:
            self.__known_auto_processes[arg].process()
        except KeyError as error:
            print(f'Invalid arg option {error.args}.')

    def __inti_know_processes(self):
        self.__known_auto_processes['B'] = B()
        self.__known_auto_processes['C'] = C()

测试示例:

import unittest
from unittest.mock import patch

from a import A


class TestA(unittest.TestCase):
    @patch("b.B")
    def test_b_call(self, mock_b):
        a = A()
        a.process('B')
        mock_b.process.assert_called_once()
python python-3.x python-unittest python-mock
2个回答
1
投票

这些帖子对我有帮助link1link2。像这样的东西应该有效。我认为它的作用是围绕 B 中的进程创建一个模拟包装器,因此,它将计算它被调用的次数。

如果您有更多见解或更好的解释,我们将不胜感激。

import unittest
from unittest.mock import patch, PropertyMock

from a import A
from b import B


class TestA(unittest.TestCase):
    @patch.object(B, 'process', new_callable=PropertyMock)
    def test_b_call(self, mock_b):
        a = A()
        mock_b.return_value = mock_b.process
        a.process('B')
        mock_b.process.assert_called_once()

如果您的代码希望返回某些内容,您还可以添加类似

mock_obj.process.return_value = (mock.MagicMock(), mock.MagicMock())
的内容,在我的实际代码中它需要 2 个参数。


0
投票

你的错误是你试图在定义类的方法而不是使用它的地方修补它。

当您修补时,您应该修补使用它们的对象/方法。您可以参考这个官方文档了解更多详情。

至于你的例子,它们应该看起来像这样:

import unittest
from unittest.mock import patch

from a import A


class TestA(unittest.TestCase):
    @patch("a.B")
    def test_b_call(self, mock_b):
        a = A()
        a.process('B')
        mock_b.process.assert_called_once()

由于您在

B Class
模块中使用了
a
,因此您应该在其中修补它。

© www.soinside.com 2019 - 2024. All rights reserved.