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

Django/DRF测试Mock Shell脚本方法报AttributeError问题求助

问题:Mock Django视图依赖的外部脚本方法时出现AttributeError

问题背景

测试Django/DRF视图方法时,该方法会调用一个仅适配其他操作系统的Shell脚本,需要Mock对应的Python函数,但运行测试时触发AttributeError,提示check_web_share_file_folder函数没有get_path_from_inode属性,实际该函数存在于对应文件中。

项目结构

django/
├── webshare/
│   ├── actions
│   │      └── check_web_share_file_folder.py
│   ├────────
│   └── tests
│           └── factories
│                    └── test_web_share_file_folder_view.py

测试代码

@patch('check_web_share_file_folder.get_path_from_inode')
def test_list_with_search_mocked(self, mock_get_attribute):
    mock_get_attribute.return_value = 'expected value'
    request = self.factory.get('/fake-url')
    force_authenticate(request, user=self.user)

    view = WebShareFileFolderViewSet.as_view({'get': 'list'})
    response = view(request)

    self.assertEqual(response.status_code, status.HTTP_200_OK)

报错信息

AttributeError: <function check_web_share_file_folder at 0x00000237FD567708> does not have the attribute 'get_path_from_inode'

目标函数(check_web_share_file_folder.py中)

def get_path_from_inode(inode):
    std, err, code = popen_wrapper([
        'sudo', 'get_path_from_inode.sh',
        str(inode)
    ])
    if code != 0:
        return False
    return str(std.strip())[1:]

解决方案

问题根源是Mock路径不正确。当前使用的@patch('check_web_share_file_folder.get_path_from_inode')是相对路径,Python误将check_web_share_file_folder识别为某个函数而非模块,因此找不到get_path_from_inode属性。

正确的Mock路径

根据项目结构,必须使用完整的模块导入路径:

@patch('webshare.actions.check_web_share_file_folder.get_path_from_inode')

原理说明

Mock的核心规则是:Mock被测试代码实际导入的路径,而非目标函数所在的原始文件路径。假设你的视图代码中是这样导入目标函数的:

from webshare.actions.check_web_share_file_folder import get_path_from_inode

或者

import webshare.actions.check_web_share_file_folder as check_module
# 调用时用 check_module.get_path_from_inode(...)

那么Mock时必须严格匹配这个导入路径,否则Python会定位到错误的对象,导致属性查找失败。

修改后的完整测试代码示例

from unittest.mock import patch
from rest_framework import status
from rest_framework.test import force_authenticate, APITestCase
from webshare.views import WebShareFileFolderViewSet

class WebShareFileFolderViewTest(APITestCase):
    def setUp(self):
        self.user = # 初始化测试用户对象
        self.factory = # 初始化请求工厂

    @patch('webshare.actions.check_web_share_file_folder.get_path_from_inode')
    def test_list_with_search_mocked(self, mock_get_path):
        mock_get_path.return_value = 'expected value'
        request = self.factory.get('/fake-url')
        force_authenticate(request, user=self.user)

        view = WebShareFileFolderViewSet.as_view({'get': 'list'})
        response = view(request)

        self.assertEqual(response.status_code, status.HTTP_200_OK)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:22:38