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

Django-nose忽略被装饰器包裹的测试用例问题求助

解决Django-nose忽略被装饰器包裹的测试用例问题

这个问题的核心原因是你的装饰器没有保留原测试函数的元数据,导致django-nose(底层依赖nose框架)无法识别被装饰后的函数是一个测试用例。下面是具体的解决方案:

第一步:用functools.wraps保留原函数元数据

nose框架通过检查函数名称(是否以test_开头)和函数的元数据(如__name__、__module__)来识别测试用例。你的装饰器返回的wrapper函数会覆盖原测试函数的这些属性,所以nose会把它当成普通函数而非测试用例。

修改你的装饰器,加入functools.wraps装饰器:

from functools import wraps
from unittest.mock import patch

def external_services_mock(f):
    @wraps(f)  # 关键:保留原测试函数的名称和元数据
    @patch('service.remote_call1')
    @patch('service.remote_call2')
    def wrapper(self, remote_call2_mock, remote_call1_mock, *args, **kwargs):
        remote_call1_mock.return_value = None
        
        def test_mocks():
            return remote_call1_mock, remote_call2_mock
        
        # 确保返回测试函数的执行结果(虽然测试方法通常不需要返回值,但保持一致性)
        return f(self, test_mocks, *args, **kwargs)
    
    return wrapper

第二步:确保测试用例的结构正确

你的测试用例需要定义在继承自django.test.TestCase(或unittest.TestCase)的类中,并且方法名以test_开头(你已经做到了这一点),示例如下:

from django.test import TestCase

class YourTestCase(TestCase):
    @external_services_mock
    def test_add_callback(self, test_mocks):
        remote_call1_mock, remote_call2_mock = test_mocks()
        
        # 执行你的测试逻辑
        # 比如调用被测试的函数,然后断言结果
        result = some_function_you_test()
        self.assertEqual(result, expected_value)

为什么这样能解决问题?

@wraps(f)会将原测试函数的__name__、__doc__、__module__等元数据复制到wrapper函数上,这样django-nose在扫描测试用例时,就能识别出这个被装饰后的函数依然是一个合法的测试用例,不会再忽略它。

另外,你的patch装饰器参数顺序是正确的(因为装饰器是从下往上应用的,所以remote_call2_mock会先被传入wrapper),这部分不需要修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 06:53:58