Patch: AssertionError: Expected '...' to have been called once. Called 0 times

Patch: AssertionError: Expected '...' to have been called once. Called 0 times

我有以下class待测

mod1/file1.py

@dataclass
class Base(metaclass=ABCMeta):

    account: Account
    ec2_id: str = ""

    def start(self):
        self.account.session.resource("ec2").instances.filter(
            InstanceIds=[self.ec2_id]
        ).start()

我创建了以下测试,

from unittest.mock import Mock, patch

    @patch('mod1.file1.Base')
    def test_start(sut):
        sut.account = Mock()
        sut.ec2_id = 'test'
        sut.start()  # sut.return_value.start() gets the same error
        sut.account.session.resource('ec2').instances.filter.assert_called_once()

然而,测试因错误而失败

AssertionError: Expected 'filter' to have been called once. Called 0 times.

代码的问题在于您正在模拟要测试的对象。您必须模拟您不想创建的 sut 实例化的任何对象(因为不需要的副作用或复杂的初始化)。 如果对象被模拟,则无法对其进行测试,因此调用修补对象 sut 肯定是错误的。

在您的情况下,您需要实例化真实的被测系统,例如数据类,并且只模拟 Account (就像你做的那样),所以这样的事情应该有效:

    def test_start():
        sut = Base()
        sut.account = Mock()
        sut.start()
        sut.account.session.resource('ec2').instances.filter.assert_called_once()

请注意,设置 sut.ec2_id 没有任何影响,因为 filter 是模拟的,参数无关紧要。

如果这确实测试了您需要测试的功能,则另当别论。