单元测试失败,提示'WSGIRequest'对象没有'city'属性

1 投票
2 回答
1435 浏览
提问于 2025-04-17 17:33

我写了一个单元测试来测试一个API……这是一个GET请求……

当我运行它时,出现了这个错误……以下是错误的详细信息……

Traceback (most recent call last):
  File "/home/arindam31/XXX-Name/mapi/tests.py", line 141, in test_get_cities
    response = self.cl.get('/mapi/latest/cities/')
  File "/usr/local/lib/python2.7/dist-packages/django/test/client.py", line 445, in get
    response = super(Client, self).get(path, data=data, **extra)
  File "/usr/local/lib/python2.7/dist-packages/django/test/client.py", line 229, in get
    return self.request(**r)
  File "/usr/local/lib/python2.7/dist-packages/django/test/client.py", line 387, in request
    response = self.handler(environ)
  File "/usr/local/lib/python2.7/dist-packages/django/test/client.py", line 84, in __call__
    response = self.get_response(request)
  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 169, in get_response
    response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
  File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py", line 218, in handle_uncaught_exception
    return callback(request, **param_dict)
  File "/home/arindam31/XXX-Name/saul/views.py", line 546, in do_handle_500
    return render_to_response("500.html", context_instance=RequestContext(request))
  File "/usr/local/lib/python2.7/dist-packages/django/template/context.py", line 177, in __init__
    self.update(processor(request))
  File "/home/arindam31/XXX-Name/saul/context_processors.py", line 46, in common_context
    ret_dict['city'] = request.city
AttributeError: 'WSGIRequest' object has no attribute 'city'

这是我的单元测试……

def test_get_cities(self):
    request = HttpRequest()
    request.city = self.c1
    response = self.cl.get('/mapi/latest/cities/')
    content = response.content
    data = json.loads(content)
    for city in City.objects.all():
        assert city.name in data
        assert data[city.name] == city.pk

在这里,self.c1是setUp部分的一个城市类型对象……HttpRequest是来自django.http的。

下面是正在测试的视图:

def get_cities(request): 
    print "1"
    if ENABLE_HTTPS_CHECK and not request.is_secure():
        return HttpResponseForbidden()
    if request.method != 'GET':
        return HttpResponseNotAllowed('Not allowed')
    city_map = _get_city_map()
    response = HttpResponse(json.dumps(city_map)
    content_type='application/json')
    response['Cache-Control'] = 'no-cache'
    return response

2 个回答

-1

我完全不明白你在这里想做什么。你创建了一个请求对象,给它设置了一个城市属性,然后又忽略了这个对象,直接使用了标准的测试客户端。我不知道你为什么会认为这个请求会被客户端用来获取数据。

老实说,我觉得你的整个设计都有问题。你没有说明在正常情况下是怎么把参数放进请求里的,通常情况下你会通过POST或GET参数来传递,而不是以某种方式把它注释到请求里。这样做当然会更容易测试,因为你可以直接把字典传给客户端调用。

0

如果你想用自己的请求对象来测试你的视图,最好直接调用这个视图。你可以使用RequestFactory来创建请求。

正如Daniel Roseman所说,如果你的请求对象有一个城市属性,但没有一些中间件来设置它,那这个属性就会出问题。你在saul/context_processors.py中显然有一些中间件需要这个属性被设置。

使用RequestFactory并直接调用视图可以完全绕过中间件,这样你就可以专注于测试你的视图(前提是这个视图可以在没有中间件的情况下正常工作)。

如果你的视图需要中间件正常运行,你可能只需要通过测试客户端登录。它有一个会话功能,可以在测试方法中使用。

撰写回答