将参数传递给 symfony 5.4 表单测试不起作用

Posted

技术标签:

【中文标题】将参数传递给 symfony 5.4 表单测试不起作用【英文标题】:Passing parameters to symfony 5.4 form test not working 【发布时间】:2021-12-23 20:11:02 【问题描述】:

我已经尝试了 5 个小时,但没有成功...我有一个 Symfony 5.3 应用程序并实现了一个不绑定到实体的搜索页面。完美运行,但是在创建通用可用性测试时,参数不会传递给控制器​​。我曾尝试使用 $_POST 数组进行模拟,将数组传递给 $client->request() 的第三个参数,但结果始终显示执行了 GET 方法并且该参数未包含在请求中。

表格是这样的:

<form class="form-search" action=" path('search_result') " method="post">
    <input name="searchwords" placeholder=" 'search.placeholder'|trans " type="text" class="input-large search-query">
    <button type="submit" class="btn search rounded"><i class="far fa-search"></i></button>
</form>

在我的控制器中可以通过以下方式访问参数“searchwords”:

$vars = Request::createFromGlobals();
$temp_searchwords = explode(' ', $vars->get('searchwords'));

现在我正尝试在通用可用性测试期间传递参数

$crawler = $client->request('POST', '/de/search/result', ["searchwords" => "test"]);

结果显示使用了GET方法,参数没有传递给Controller。我还尝试使用 $_POST 系统变量进行模拟:

$_POST = ["searchwords" => "test strings"]

Request::createFromGlobals();在我的控制器中没有给出任何参数,可能是因为使用了 GET 方法而不是我的 $client->request() 调用中请求的“POST”。

从官方 Symfony 5.3 文档中进行的另一次尝试也失败了,参数未传递给我的控制器:

$buttonCrawlerNode = $crawler->selectButton('');
$form = $buttonCrawlerNode->form();
$form['searchwords'] = "test string";
// at this point the $form object contains the parameter "searchwords" and the value "test string"
$crawler = $client->submit($form);

问题:如何将参数传递给我的控制器并在我的测试中强制执行“POST”请求?如前所述,搜索在真实的浏览器环境中运行良好。

【问题讨论】:

为什么不使用 symfony Form 组件来制作你的表单呢?我认为您将通过这种方式轻松检索参数。 一个表单组件与一个实体相关联,我不需要也不想要一个不被持久化在数据库中的实体。恐怕它也可能会创建一个死数据库表。我看到两个问题,其中一个需要解决:当篡改 $_POST[] 数组时,“Request::createFromGlobals();”行不会从 $_POST 数组中提取全局变量。或:“$client->request('POST', '/de/search/result', ["searchwords" => "test"]);"应该按要求发帖,现在它出于某种未知原因执行 GET 查询:( A form component is tied to an Entity 不需要,你可以构建一个没有实体的表单组件 我花了一些时间玩弄控制器、Twig 资源和 WebTest。简而言之,我无法创建一个工作测试。为这样一个简单的过程使用 Symfony 的 Forms 机制的开销是不切实际的。然而,总共 7 个小时后,我现在想通了:我通过 get() 调用了 post 变量。但是有必要从请求对象中获取它们。然后测试也有效! 【参考方案1】:

如果有人发现自己处于这种情况:

我通过以下函数调用了 post 变量“searchword”。

$vars = Request::createFromGlobals();
$searchwords = explode(' ', $vars->get('searchwords'));

但是,这只适用于浏览器,因为 WebTest 会创建一个请求对象,而无需通过全局变量进行转移。

真正的解决方案是在控制器函数中自动装配请求对象并将其用于参数检索:

public function searchResultAction($_locale, DuddeSearch $ds, Request $request)

    [...]
    $searchwords = explode(' ', $request->get('searchwords'));

这个问题是我初学者的错误。在 Symfony 的“最佳实践”中明确且突出地提到了自动装配。唯一的困难是我的解决方案在浏览器中完美运行。

【讨论】:

以上是关于将参数传递给 symfony 5.4 表单测试不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何自动将用户对象传递给 Symfony 3 表单?

Symfony2 服务容器 - 将普通参数传递给服务构造函数

如何将令牌存储作为参数传递给 Symfony 3.4 中的事件监听器

将参数传递给 django 表单

Zoho Creator Deluge InvokeUrl:如何将表单参数传递给第三方表单?

将参数传递给FormView Django中的表单