Laravel 5.1 PHPUnit - press() 给了我“无法访问的字段”“”

Posted

技术标签:

【中文标题】Laravel 5.1 PHPUnit - press() 给了我“无法访问的字段”“”【英文标题】:Laravel 5.1 PHPUnit - press() gives me 'Unreachable field ""' 【发布时间】:2016-03-04 19:24:07 【问题描述】:

当尝试调用press() 方法时,我总是得到

InvalidArgumentException:无法访问的字段“”

在那一行。

根据文档:

“按下”具有给定文本或名称的按钮。

我的方法:

press('Create') 

我的按钮是

<button class="btn btn-lg btn-primary" type="submit" name="submit">Create</button> 

我也尝试使用name 获得相同的结果。

我也尝试过submitForm('Create'),它可以工作,但是seeInDatabase('employees', ['email' =&gt; 'john@email.com']) 总是失败。

无法在数据库表 [employees] 中找到与属性 ["email":"john@email.com"] 匹配的行。

这是我的完整方法

public function testExample()


  $this->actingAs(\App\Employee::where('username', 'grant')->first())
    ->visit('/employees/create')
    ->type('john', 'username')
    ->type('1234', 'password')
    ->type('john@email.com', 'email')
    ->submitForm('Create')
    ->seeInDatabase('employees', ['email' => 'john@email.com'])
    ->see('Employee Directory');

更新 1

这是我的表格:

!! Form::open(['route' => 'employees.store', 'method' => 'POST']) !!
  @include('employees.form')
!! Form::close() !!

如您所见,我的字段不可能在表单之外。

【问题讨论】:

我遇到了类似的问题。这可能与客户端验证失败有关。 我认为这与按钮无关,而是与表单中提交的其他字段有关。 "" 表明它可能与具有数组名称的输入有关(例如 name="email[]")。您可以发布您的表格样本吗? 如果您的输入具有 WebSpanner 规定的数组名称,您可以为输入提供一个与名称相同但没有数组声明的 id,并在 phpUnit 中引用不带括号的输入。这应该可以解决您的问题并允许 PHPUnit 看到提交按钮。 【参考方案1】:

我不确定您的问题的确切原因是什么,但可能是几件事。 我会发表评论,但我还没有足够的声誉。

首先,您是否通过验证器运行纯 html?如果它给您任何语法错误,请尝试修复它们并再次运行单元测试。 (你可以试试这个https://validator.w3.org/,复制粘贴你的html)

另一个原因可能是您有一些 javascript 修改了您的 DOM,而 Laravel 测试无法处理。

最后,您可以尝试将&lt;button&gt; 的“值”属性设置为“创建”

<button class="btn btn-lg btn-primary" type="submit" name="submit" value="Create">Create</button>

或者将&lt;button&gt; 更改为&lt;input&gt;,并使用type 属性"submit"value 更改为"Create"

<input type="submit" class="btn btn-lg btn-primary" name="submit" value="Create" />

【讨论】:

【参考方案2】:

根据经验,无法访问的字段错误通常是由位于 &lt;form&gt; 元素之外的按钮引起的,我有一个类似的场景,页面的另一部分通过 $request 传递给控制器​​,但因为它不是在与其他所有内容相同的直接表单元素中,PHPUnit 无法将其与表单关联。

可能值得将方法从 press() 更改为 click(),它只是寻找可以点击的内容,而不是尝试将提交按钮与表单匹配。

同样如上所述,PHPUnit 自身无法测试 JavaScript(当然,如果您使用的是 Javascript),您需要像 Selenium 这样的东西来做到这一点。

没有标记很难说,你能张贴你的表单的标记吗?

【讨论】:

就是这样。我有两种形式:标准形式和 ajax 形式。无法测试 ajax 表单,但这就是问题所在。【参考方案3】:

造成这种情况的主要原因是您的提交按钮看起来像这样。 &lt;button type="submit" name="submit" class="btn btn-primary"&gt;Submit&lt;/button&gt;。当您将按钮的文本更改为提交以外的其他文本时,它会正常工作。例如&lt;button type="submit" name="submit" class="btn btn-primary"&gt;Create&lt;/button&gt;

【讨论】:

【参考方案4】:

前面的建议没有涵盖让两个提交按钮具有相同值的业务需求。

我们需要做的是,覆盖默认的 Laravel XPath 表达式。

我们将告诉 Laravel 查找具有我们特定 XPath 的元素(第二个提交按钮),而不是查找带有文本的第二个提交按钮的第一个实例。

    $this->visit(route('user.login'));

    // replace `login-btn-2` with the id of your second button
    $button = $this->crawler->filterXPath('//*[@id="login-btn-2"]'); 

    $form = $button->form($inputs = ['email' => $user->email, 'password' => $password,]);

    $this->makeRequestUsingForm($form);

    $this->see(route('user.loggedin.dashboard'));

加分 如果您是 XPath 的新手,您可以在 Chrome 浏览器上右键单击检查过的源代码。你想要的选项是Copy > Copy as XPath

【讨论】:

【参考方案5】:

您可能会发现它适用于 submitForm 方法:

$this->submitForm('Create', ['username' => 'john']);

【讨论】:

以上是关于Laravel 5.1 PHPUnit - press() 给了我“无法访问的字段”“”的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.1 使用 JSON 的 API 的 PHPUnit 测试

How Use PHPUnit Test in Laravel 5.1

基于 Laravel 开发博客应用系列 —— 从测试开始:创建项目和PHPUnit

laravel 4 无法让 phpunit 测试工作

将 phpunit 安装到 Laravel 4 站点

Laravel - PHPUnit 中的伪造路由