我编写了一段代码,在 else 情况下调用一个函数,该函数返回一个字符串。我嘲笑了它并断言它会被调用一次。但由于某种原因,这失败了。这减少了我的代码覆盖率,在下面的 else 条件下仅用 1 行来表示
get_sync_column()
。
原创功能
@dataclass(frozen=True)
class RMTable():
sync_column: ClassVar[str] = None
def __post_init__(self) -> None:
if self.sync_column is None:
object.__setattr__(self, "sync_column", self.cal_sync_column())
def cal_sync_column(self) -> str:
if not feature_flag():
return "_synced"
else:
return get_sync_column() #returns str
测试功能
def test_sync_column():
with patch("my_module.feature_flag") as feature_flag_mock:
with patch("my_module.get_sync_column") as mock_sync_column:
feature_flag_mock.return_value = True
rm_table_mock = MagicMock(spec=RMTable)
rm_table_mock.cal_sync_column.return_value = "FLAG_1"
result = rm_table_mock.cal_sync_column()
assert result == "FLAG_1"
mock_sync_column.assert_called_once()
错误
AssertionError: Expected 'get_sync_column' to have been called once. Called 0 times.
RMTable
您必须创建
RMTable
的实例,而不是 MagicMock
的实例,因此最重要的更改是以下替换:
rm_table_mock = MagicMock(spec=RMTable) ---> rm_table = RMTable()
仅设置
spec=RMTable
是不够的,因为它只会强制实例 rm_table_mock
在 RMTable
中声明属性。rm_table_mock.cal_sync_column()
时,它不会执行真正的方法cal_sync_column()
,而只调用一个模拟对象,该对象不会调用函数get_sync_column()
。
如果使用以下测试代码,则测试通过:
from unittest.mock import patch, MagicMock, Mock
from my_module import RMTable
def test_sync_column():
with patch("my_module.feature_flag") as feature_flag_mock:
with patch("my_module.get_sync_column") as mock_sync_column:
feature_flag_mock.return_value = True
#rm_table_mock = MagicMock(spec=RMTable) # <--- your instruction is commented
# creation of a real instance of the class RMTable
rm_table = RMTable()
#rm_table_mock.cal_sync_column.return_value = "FLAG_1" # <--- your instruction is commented
# set return value for the mock of the function get_sync_column()
mock_sync_column.return_value = "FLAG_1"
#result = rm_table_mock.cal_sync_column() # <--- your instruction is commented
result = rm_table.cal_sync_column()
assert result == "FLAG_1"
mock_sync_column.assert_called_once()
if __name__ == '__main__':
test_sync_column()