如何正确Mock filecmp模块的cmp方法以避免访问文件系统?
解决filecmp.cmp Mock后仍访问实际文件系统的问题
问题核心在于你mock的路径和被测代码中实际引用filecmp.cmp的路径不匹配,mock的核心原则是:mock对象在被测代码中被使用的位置,而非它被定义的位置。以下分两种常见场景给出正确的Mock方式:
场景1:被测代码中导入整个filecmp模块
假设同步函数所在模块(比如sync.py)代码如下:
import filecmp import os import shutil def sync_to_cache(source_path, cache_path): # 检查缓存文件是否存在且与源文件一致 if os.path.exists(cache_path) and filecmp.cmp(source_path, cache_path): return # 同步文件到缓存 shutil.copy(source_path, cache_path)
此时测试代码需要mocksync.filecmp.cmp(即被测模块内的filecmp引用),而非全局的filecmp.cmp。示例测试代码:
from unittest.mock import patch import sync def test_sync_when_cache_outdated(): # 同时mock被测模块内的filecmp.cmp和os.path.exists with patch("sync.filecmp.cmp") as mock_cmp, patch("sync.os.path.exists") as mock_exists: # 模拟缓存文件存在但与源文件不一致 mock_exists.return_value = True mock_cmp.return_value = False sync.sync_to_cache("test_source.txt", "test_cache.txt") # 验证mock被正确调用 mock_exists.assert_called_once_with("test_cache.txt") mock_cmp.assert_called_once_with("test_source.txt", "test_cache.txt") # 若同步逻辑用到shutil.copy,也需要mock并验证 with patch("sync.shutil.copy") as mock_copy: mock_copy.assert_called_once_with("test_source.txt", "test_cache.txt")
场景2:被测代码中直接导入cmp函数
如果被测模块是直接导入cmp:
from filecmp import cmp import os import shutil def sync_to_cache(source_path, cache_path): if os.path.exists(cache_path) and cmp(source_path, cache_path): return shutil.copy(source_path, cache_path)
此时需要mocksync.cmp(被测模块内的cmp直接引用):
from unittest.mock import patch import sync def test_sync_when_cache_missing(): with patch("sync.cmp") as mock_cmp, patch("sync.os.path.exists") as mock_exists: # 模拟缓存文件不存在 mock_exists.return_value = False sync.sync_to_cache("test_source.txt", "test_cache.txt") # 验证cmp未被调用(因为缓存不存在直接进入同步) mock_cmp.assert_not_called() mock_exists.assert_called_once_with("test_cache.txt")
关键注意事项
- 务必确保mock的路径与被测代码中使用目标函数/模块的路径完全匹配,否则mock不会生效,代码仍会调用原函数访问文件系统
- 检查同步函数中所有涉及文件系统的操作(如
os.path.exists、shutil.copy等),都需要对应mock,避免遗漏导致的文件系统访问 - 通过设置
return_value可以模拟不同业务场景:比如mock_cmp.return_value = True模拟文件一致,False模拟文件不一致
内容的提问来源于stack exchange,提问作者Stephen
相关产品推荐
相关产品推荐

