Django单元测试客户端响应有空的上下文 [英] Django unit test client response has empty context

查看:155
本文介绍了Django单元测试客户端响应有空的上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是通过测试:

  def test_home(self):
c = Client()
resp = c.get('/')
self.assertEqual(resp.status_code,200)
self.assertTrue(resp.context中的'a_formset')

以下是失败的测试:

  def test_number_initial_number_of_forms(self):
c = Client()
resp = c.get('/')
self.assertEqual(resp.context ['a_formset']。total_form_count(),1)

在第二个测试中,我收到错误 TypeError:'NoneType'对象没有属性'__getitem __'



如果我执行第二个测试为

  def test_number_initial_number_of_forms )
c = Client()
resp = c.get('/')
self.assertTrue(resp.context中的'a_formset')
self.assertEqual(resp。上下文['a_formset']。total_form_count(),1)

我收到错误 TypeError:类型NoneType的参数不可迭代。我在第二次测试中通过print语句确认response.content包含我期望获得的页面,状态代码是正确的,并且该模板是正确的。但是在第二个测试中,响应的上下文一直是 None



我正在运行我的Django单元测试标准的python manage.py test ...界面,所以我不相信我遇到了上下文是从shell 的问题。



这是怎么回事?



编辑



如果我添加打印类型(resp.context ['a_formset'])到每个测试,为工作测试我得到< class'django.forms.formsets.AFormFormSet'> 。对于非工作测试,我得到 TypeError:'NoneType'对象没有属性'__getitem __'再次。

解决方案

今天我遇到同样的问题。 第二个测试获得相同的页面没有任何response.context



我做了一个研究,发现
1)测试客户端使用信号填充上下文,
2)我的视图方法没有被调用第二个测试



我打开一个调试器,发现有罪的一个是缓存中间件。知道我发现这张票和这个 SO问题(后者有一个解决方案)。



简而言之,第二个请求是从缓存提供的,而不是从视图提供,因此视图不会执行,测试客户端没有得到信号,没有能力填充上下文。



我无法禁用我的项目的缓存中间件,所以我添加了下一个黑客行到我的设置:

 如果sys.argv中的test:
CACHE_MIDDLEWARE_SECONDS = 0

希望这有助于某人


I have a unit test that's failing in an assertion that passes in another test in the same test case class.

Here's the passing test:

def test_home(self):
    c = Client()
    resp = c.get('/')
    self.assertEqual(resp.status_code, 200)
    self.assertTrue('a_formset' in resp.context)

Here's the failing test:

def test_number_initial_number_of_forms(self):
    c = Client()
    resp = c.get('/')
    self.assertEqual(resp.context['a_formset'].total_form_count(), 1)

In the second test, I get the error TypeError: 'NoneType' object has no attribute '__getitem__'.

If I execute the second test as

def test_number_initial_number_of_forms(self):
    c = Client()
    resp = c.get('/')
    self.assertTrue('a_formset' in resp.context)
    self.assertEqual(resp.context['a_formset'].total_form_count(), 1)

I get the error TypeError: argument of type 'NoneType' is not iterable. I've confirmed via print statements in the second test that the response.content contains the page I expect to get, that the status code is correct, and that the template is correct. But the response's context is consistently None in the second test.

I'm running my Django unit tests through the standard "python manage.py test ..." interface, so I don't believe I'm running into the "context is empty from the shell" issue.

What's going on with this?

Edit:

If I add print type(resp.context['a_formset']) to each test, for the working test I get <class 'django.forms.formsets.AFormFormSet'>. For the non-working test, I get TypeError: 'NoneType' object has no attribute '__getitem__' again.

解决方案

Today I run into the same issue. The second test gets same page has nothing in response.context

I made a research and found that 1) test client uses signals to populate context, 2) my view method is not called for the second test

I turned on a debugger and found that the guilty one is 'Cache middleware'. Knowing that I found this ticket and this SO question (the latter has a solution).

So, in short: the second request is served from cache, not from a view, thus a view is not executed and test-client doesn't get the signal and have no ability to populate context.

I can not disable cache middleware for my project, so I added next hack-lines into my settings:

if 'test' in sys.argv:
   CACHE_MIDDLEWARE_SECONDS = 0

Hope this helps someone

这篇关于Django单元测试客户端响应有空的上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆