8

在添加 ArrayCollection 成员的表单功能测试中,有以下语句:

$form['client[members][1][fname]'] = 'Benny';

字段名称已通过 DOM 检查器进行验证。

此行的控制台输出为:

InvalidArgumentException: Unreachable field "members"

G:\Documents\workspace\sym\vendor\symfony\symfony\src\Symfony\Component\DomCrawler\Form.php:459
G:\Documents\workspace\sym\vendor\symfony\symfony\src\Symfony\Component\DomCrawler\Form.php:496
G:\Documents\workspace\sym\vendor\symfony\symfony\src\Symfony\Component\DomCrawler\Form.php:319
G:\Documents\workspace\sym\src\Mana\ClientBundle\Tests\Controller\ClientControllerTest.php:57

应该使用什么方法来测试添加 ArrayCollection 成员?

根据要求进行编辑(注意,开启跟踪重定向):

    //link to trigger adding household member form
    $link = $crawler->selectLink('Add household member')->link();
    $crawler = $client->click($link);
    $form = $crawler->selectButton('Add client')->form();
    $form['client[members][1][fname]'] = 'Benny';
    $form['client[members][1][dob]'] = "3/12/1999";
    $crawler = $client->submit($form);
    $this->assertTrue($crawler->filter('html:contains("Client View Form")')->count() > 0);
4

4 回答 4

9

我只是遇到了同样的问题,经过一番研究,我找到了一个对我有帮助的解决方案。 从 Collection 表单类型中删除字段的解决方案 这篇文章并不是您要找的,这篇文章是用于删除元素而不是添加新元素。但原理是一样的。我所做的而不是$form->setValues() ... $form->getPhpValues()我创建了一个数组,并发布了

在下面的示例configurations中,表单的字段是Collection

    $submitButton = $crawler->selectButton(self::BUTTON_ADD_APPLICATION);
    $form = $submitButton->form();
    $values = array(
        'Setup' => array(
            '_token' => $form['Setup[_token]']->getValue(),
            'name'   => 'My New Setup',
            'configurations' => array(
                0 => array(
                    'country' => 'HUN',
                    'value'   => '3',
                ),
                1 => array(
                    'country' => 'GBR',
                    'value'   => '0',
                ),
            ),
        ),
    );

    $client->request($form->getMethod(), $form->getUri(), $values);

希望能帮助到你!并感谢 sstok 的原始解决方案!

于 2013-03-21T10:56:04.640 回答
5

这可以通过从submit()方法中调用稍作修改的代码来完成:

// Get the form.
$form = $crawler->filter('button')->form();

// Get the raw values.
$values = $form->getPhpValues();

// Add fields to the raw values.
$values['task']['tag'][0]['name'] = 'foo';
$values['task']['tag'][1]['name'] = 'bar';

// Submit the form with the existing and new values.
$crawler = $this->client->request($form->getMethod(), $form->getUri(), $values,
    $form->getPhpFiles());

// The 2 tags have been added to the collection.
$this->assertEquals(2, $crawler->filter('ul.tags > li')->count());

此示例中包含新闻值的数组对应于一个表单,其中您有一个包含这些names 的字段:

<input type="…" name="FORM_NAME[COLLECTION_NAME][A_NUMBER][FIELD_NAME_1]" />
<input type="…" name="FORM_NAME[COLLECTION_NAME][A_NUMBER][FIELD_NAME_2]" />

使用此代码,表单中已经存在现有字段(包括令牌),这意味着您不需要添加所有字段。

字段的数量(索引)无关紧要,PHP 会合并数组并提交数据,Symfony 会在相应的字段中转换这些数据。

您还可以从集合中删除元素:

// Get the values of the form.
$values = $form->getPhpValues();

// Remove the first tag.
unset($values['task']['tags'][0]);

// Submit the data.
$crawler = $client->request($form->getMethod(), $form->getUri(),
    $values, $form->getPhpFiles());

// The tag has been removed.
$this->assertEquals(0, $crawler->filter('ul.tags > li')->count());

来源:http ://symfony.com/doc/current/book/testing.html#adding-and-removing-forms-to-a-collection

于 2016-03-18T13:05:15.010 回答
2

如果你用 javascript 修改表单,你不能用 symfony 测试框架来测试它。这样做的原因是 symfony 提供的 DomCrawler 只获取静态 HTML 并对其进行解析,而没有考虑到具有图形用户界面(主要是 javascript)的浏览器会进行的任何操作。

如果你需要测试一个大量 javascript 的项目,你需要使用一些框架,它要么使用浏览器的引擎(例如 Selenium),要么可以解释 javascript 并在 DOM 上执行所有更改(例如 Zombie.js)。

一个很好的框架是 Mink,它是测试框架和执行请求并解析结果的实际客户端之间的一层。它提供了一个 API 来使用一个非常简单的 PHP HTML Parser(类似于 symfony 使用的 DomCrawler)、Selenium、Zombie.js 等等。

于 2013-03-19T22:18:24.820 回答
0

我有一个类似的问题,在我的情况下,我意识到这是因为我没有使用正确的爬虫,我使用的是前一页中的一个,形式略有不同。因此,我认为这是提供适合我的解决方案的好地方。

通过在正确的网页上获取新的爬虫,它可以工作

    $crawler = $client->getCrawler();
    //processing the form
    // ...

为了避免错误,我使用了语法

$crawler = $client->submitForm('Add client', [
            'client[members][1][fname]' => 'Benny',
            'client[members][1][dob]' => "3/12/1999",
        ]);
于 2021-11-03T02:31:11.010 回答