测试在 else 条件下调用的函数

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

我编写了一段代码,在 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.
python unit-testing testing mocking pytest
1个回答
0
投票

创建
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()
© www.soinside.com 2019 - 2024. All rights reserved.