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
是模拟的,参数无关紧要。
如果这确实测试了您需要测试的功能,则另当别论。
我有以下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
是模拟的,参数无关紧要。
如果这确实测试了您需要测试的功能,则另当别论。