小编典典

Django单元测试客户端响应具有空上下文

python

我有一个单元测试,它的断言在同一测试用例类中的另一个测试中通过失败。

这是通过测试:

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__'了。


阅读 153

收藏
2021-01-20

共1个答案

小编典典

今天,我遇到了同样的问题。在 第二次 测试得到相同的页面无关,在response.context

我进行了一项研究,发现1)测试客户端使用信号填充上下文,2)第二个测试未调用我的view方法

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

因此,简而言之: 第二个请求是从缓存而不是从视图提供的,因此视图不会被执行,并且test-client无法获取信号,也无法填充上下文。

我无法为我的项目禁用缓存中间件,因此我在设置中添加了下一个hack-line:

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

希望这可以帮助某人

2021-01-20