You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用Mock库做单元测试触发ModuleNotFoundError问题求助

问题原因及解决方案

1. ModuleNotFoundError 报错原因

你当前在tests目录下直接执行测试文件,Python 默认只会将当前工作目录(也就是/path/to/artwork_grabber/tests)加入模块搜索路径,上层的项目根目录不在搜索路径里,所以找不到内层的artwork_grabber包。

对应解决方法(任选其一即可)

  • 方法1:切换工作目录到最外层的artwork_grabber项目根目录,使用模块方式运行测试:
    python -m unittest tests/test_module.py
    
    这种方式会自动将当前根目录加入Python的模块搜索路径,可正常识别包。
  • 方法2:在测试文件开头手动添加项目根目录到搜索路径,在test_module.py最顶部加入以下代码:
    import sys
    from pathlib import Path
    # 将当前文件的父目录的父目录(也就是项目根目录)加入搜索路径
    sys.path.append(str(Path(__file__).parent.parent.resolve()))
    
  • 方法3:将项目配置为可安装包,在项目根目录新增pyproject.toml配置文件后执行pip install -e .,将包安装到当前Python环境中,可全局导入。

2. 测试代码本身的逻辑错误

解决导入问题后你还会遇到Mock使用错误的问题,当前测试写法有三个明显问题:

  • 你导入的是from mock import patch,但装饰器写的是@mock.patch,缺失mock的导入,要么把装饰器改为@patch,要么新增import mock的导入语句。
  • 你Patch的是要测试的create_search_term函数本身,相当于直接把待测逻辑替换成了假的返回值,完全无法测试真实的函数逻辑。正确做法是Patch函数依赖的两个外部调用:os.path.isfile和TinyTag.get。
  • 原函数逻辑里存在错误:if str(path.isfile(file_path_to_song)): 这行代码会把布尔值转为非空字符串,不管文件是否存在判断都会为真,应该改为if path.isfile(file_path_to_song):。

修正后的测试代码示例

from unittest import TestCase
from mock import patch
import unittest
# 导入模块后可以直接用模块名访问内部对象
import artwork_grabber.helpers as helpers

class UnitTests(TestCase):
    mock_song_info = {
        "album": "A Deeper Understanding",
        "artist": "The War On Drugs"
    }

    # 同时mock两个依赖对象,注意装饰器参数顺序和函数参数顺序是反过来的
    @patch('artwork_grabber.helpers.path.isfile')
    @patch('artwork_grabber.helpers.TinyTag.get')
    def test_create_search_term(self, mock_tinytag_get, mock_isfile):
        # 配置mock的返回值
        mock_isfile.return_value = True
        mock_tag = mock_tinytag_get.return_value
        mock_tag.get_album.return_value = self.mock_song_info["album"]
        mock_tag.get_artist.return_value = self.mock_song_info["artist"]
        
        actual_result = helpers.create_search_term("fake/path/to/song.mp3")
        expected_result = "The War On Drugs A Deeper Understanding Album Cover"
        self.assertEqual(actual_result, expected_result, "Expected the search terms to match.")

if __name__ == "__main__":
    unittest.main()

内容的提问来源于stack exchange,提问作者mgermaine93

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:06:03