Django单元测试重定向报错:dict对象无url属性问题排查
Django视图测试中AttributeError问题解决
问题场景
视图函数代码:
def my_function(request): session = create_something('some_random_string') return redirect(session.url, code=303)
测试代码:
import unittest from django.test import TestCase from unittest.mock import patch from my_app.views import my_function class TestMyFunction(TestCase): @patch('my_app.views.create_something', return_value={ "url": "https://tiagoperes.eu/" }) def test_my_function(self, mock_create_something): response = self.client.get("/my-function/")
执行测试时报错:
AttributeError: 'dict' object has no attribute 'url'
问题原因
视图里调用create_something后,是通过属性访问(session.url)获取地址的,但测试中mock的返回值是字典,字典只能通过键取值(session["url"]),两者访问方式不匹配,因此触发属性不存在的错误。
解决方法
把mock的返回值改成具有url属性的模拟对象,有两种常用方式:
方法1:使用MagicMock
直接用unittest.mock.MagicMock构造带属性的对象:
from unittest.mock import patch, MagicMock # ... @patch('my_app.views.create_something', return_value=MagicMock(url="https://tiagoperes.eu/")) def test_my_function(self, mock_create_something): response = self.client.get("/my-function/") # 可添加断言验证结果 self.assertEqual(response.status_code, 303) self.assertEqual(response.url, "https://tiagoperes.eu/")
方法2:构造简单类/namedtuple
如果需要更明确的结构,可以自己定义类或者用collections.namedtuple:
from collections import namedtuple # ... SessionMock = namedtuple('SessionMock', ['url']) @patch('my_app.views.create_something', return_value=SessionMock(url="https://tiagoperes.eu/")) def test_my_function(self, mock_create_something): response = self.client.get("/my-function/") # 断言逻辑同上
类似问题场景
- 当mock Django模型类时,若错误返回字典而非模拟对象,后续代码若期望模型属性,可能触发
TypeError: quote_from_bytes() expected bytes错误 - 未给mock设置
return_value时,默认返回的Mock对象若被当作字符串/字节使用,会触发TypeError: expected string or bytes-like object错误
内容的提问来源于stack exchange,提问作者Tiago Peres
相关产品推荐
相关产品推荐

