在POST请求中显式传递自填充数据

2024-04-20 06:21:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我想测试更新视图的重定向。你知道吗

阅读文档,查看源代码,我发现: 更新视图实例自我客体在处理请求之前(这有助于将表单字段设置为当前值)

这是我想要的行为,但在测试过程中给我带来了麻烦。你知道吗

我的型号.py你知道吗

class Project(models.Model):

    title = models.CharField(max_length=50)
    description = models.CharField(max_length=200, blank=True, default="")
    # Other fields

你知道吗视图.py你知道吗

class UpdateProject(LogInRequiredMixin, UpdateView):

    form_class = ProjectUpdateForm
    template_name = 'project/create.html'

在测试中: (我创建了一个项目,并在设置中设置了大多数内容)

def test_redirection(self):
        # After updating project, users should land on correct page.[View Project page].
        self.client.login(username=self.owner.email, password=self.password)
        response = self.client.post(self.url, follow=True) # This will give error, since it requires Title field
        self.assertRedirects(response, reverse('project:show',
                                                kwargs={'project_id': self.project.id}))

现在,我知道我可以用数据字段显式地传递title,但是如果我稍后在模型中更改字段,这个测试也会失败,这是不应该的[它的唯一目的是检查重定向,还有其他处理表单验证的测试,等等]

所以,我的问题是:有没有一种方法可以像Update视图那样模拟Post请求(即,通过将对象上下文设置为预填充的值并只覆盖更改的值来传递数据上下文)


Tags: pyselfprojectclient视图truetitlemodels
2条回答

这个观点大概只会在成功的时候改变方向。如果您没有传递足够的信息使视图成功,那么它就不应该重定向。所以听起来好像你想要一些不可能的东西-你想测试代码在一种情况下做什么,而不是你正在设置的情况。你知道吗

我的问题是:这个测试的价值是什么?为什么不把它放在测试的最后,检查是否成功呢?你知道吗

我理解通常的测试咒语是你只对一件事进行测试,但我认为这对于这种场景来说是不切实际的,而且代价是围绕某件事的内部进行的脆弱测试。你知道吗

另一种方法是,在编写测试时如下所示:

def _submit_good_form_data(self):
    response = self.client.post(self.url, follow=True, data={'title':'The title')

def test_form_success(self):
    response = self._submit_good_data()
    # asserts here 

def test_redirection(self):
    response = self._submit_good_data()
    # asserts here 

这样,当表单的性质发生变化时,您只有一个地方可以更新。你知道吗

然而,我怀疑这是否真的值得,因为您正在显著地增加测试运行的长度,并且它实际上没有给您真正想要的测试独立性(视图中的错误将导致两个测试都失败)。你知道吗

复制幕后机器的一种方法:

    get_response = self.client.get(self.url)
    response = self.client.post(self.url, data=get_response.context['object'].__dict__, follow=True)
    self.assertRedirects(response, reverse('project:show', kwargs={'project_id': self.project.id}))

不是很漂亮,但基本上是幕后的东西。你知道吗

相关问题 更多 >