Django单元测试客户端响应具有空上下文
问题内容:
我有一个单元测试,它的断言在同一测试用例类中的另一个测试中通过失败。
这是通过测试:
def test_home(self):
c = Client()
resp = c.get('/')
self.assertEqual(resp.status_code, 200)
self.assertTrue('a_formset' in resp.context)
这是失败的测试:
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' object has no attribute '__getitem__'
。
如果我执行第二项测试
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)
我得到了错误TypeError: argument of type 'NoneType' is not iterable
。我已经通过第二个测试中的打印语句确认了response.content包含了我希望获得的页面,状态代码正确并且模板正确。但是,响应的上下文None
在第二个测试中始终如一。
我正在通过标准的“ python manage.py test
…”界面运行Django单元测试,所以我不相信自己会遇到“上下文从外壳为空”的问题。
这是怎么回事?
编辑:
如果我添加print type(resp.context['a_formset'])
到每个测试中,则对于工作测试,我会得到<class 'django.forms.formsets.AFormFormSet'>
。对于非工作测试,我又得到TypeError: 'NoneType' object has no attribute '__getitem__'
了。
问题答案:
今天,我遇到了同样的问题。在 第二次 测试得到相同的页面无关,在response.context
我进行了一项研究,发现1)测试客户端使用信号填充上下文,2)第二个测试未调用我的view方法
我打开调试器,发现罪魁祸首是“缓存中间件”。知道我找到了这张票和这个SO问题(后者有一个解决方案)。
因此,简而言之: 第二个请求是从缓存而不是从视图提供的,因此视图不会被执行,并且test-client无法获取信号,也无法填充上下文。
我无法为我的项目禁用缓存中间件,因此我在设置中添加了下一个hack-line:
if 'test' in sys.argv:
CACHE_MIDDLEWARE_SECONDS = 0
希望这可以帮助某人