拉威尔的phpunit测试失败了。转到意外页面。只有在测试中才会发生

拉威尔的phpunit测试失败了。转到意外页面。只有在测试中才会发生,php,laravel,unit-testing,laravel-5,phpunit,Php,Laravel,Unit Testing,Laravel 5,Phpunit,因此,我有一个页面,上面有一个值为“Create”的按钮。当我单击“创建”按钮时,不填写任何字段,它将验证表单并在同一页面上显示错误消息。当我在浏览器中这样做时,它工作得很好,但是当我使用phpunit时,它会产生意想不到的结果,我不知道为什么 以下是我的集成测试: public function testCreateValidation() { $this->visit(route('patients.i

因此,我有一个页面,上面有一个值为“Create”的按钮。当我单击“创建”按钮时,不填写任何字段,它将验证表单并在同一页面上显示错误消息。当我在浏览器中这样做时,它工作得很好,但是当我使用
phpunit
时,它会产生意想不到的结果,我不知道为什么

以下是我的集成测试:

public function testCreateValidation()                                     
{ 
    $this->visit(route('patients.indexes.create', $this->patient->id));    
    $this->press('Create');                                                
    $this->seePageIs(route('patients.indexes.create', $this->patient->id));              
}   
这就是结果:

There was 1 failure:
1) Tests\Integration\IndexControllerTest::testCreateValidation
Did not land on expected page [http://localhost/patients/69/indexes/create].

Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'http://localhost/patients/69/indexes/create'
+'http://localhost/patients'

/vagrant/vendor/laravel/framework/src/Illuminate/Foundation/Testing/InteractsWithPages.php:141
/vagrant/tests/Integration/IndexControllerTest.php:51
我不明白为什么它被重定向到
患者
页面

下面是正在测试的Laravel
create
方法:

public function create($id)                                                         
{                                                                                   
    $index = $this->indexes->newInstance();                                         
    $patient = $this->patients->findOrFail($id);                                    

    return view('patient.index.create', ['index' => $index, 'patient' => $patient]);
} 
以下是
创建
视图的相关部分:

<?= Form::open(['route' => array('patients.indexes.store', $patient->id), 'class' => 'form-horizontal']) ?>
    @include('patient.index._form')
    <?= Form::submit('Create', ['class' => 'btn btn-primary']) ?>
<?= Form::close() ?> 
我还使用FormRequest验证输入:

public function rules()                   
{                                         
    return [                              
        'index_title' => 'required',      
        'index_description' => 'required',
    ];                                    
}  
因此,本质上,由于它在
IndexRequest
中的验证失败,
IndexRequest
应该将其返回给
患者索引。创建查看和显示错误。但由于某些原因,它被踢到了“患者”页面(这只发生在测试中,如果我通过手动单击浏览器中的“创建”按钮进行尝试,它将按预期工作)


我以前有过这个问题,但从来没有解决过。有什么想法吗?

听起来你好像有问题。在浏览器中导航到表单时,Laravel会在浏览器的Cookie和请求标题中存储一个。然后,当您提交表单时,它会查找该令牌以确保您是提交表单的人

当您使用PHPUnit进行测试时,该令牌不会被发送,因此您要么自己发送,要么必须从检查令牌的中间件中排除测试。排除测试是更简单的方法

在Laravel5.0中,我通过覆盖
VerifyCsrfToken
中间件中的
handle()
方法实现了这一点

类VerifyCsrfToken扩展BaseVerifier{
//重写BaseVerifier类中的handle()方法
公共函数句柄($request,Closure$next){
//当应用程序环境正在“测试”时,跳过CSRF验证。
如果(应用程序()->环境()=“测试”){
返回$next($request);
}
返回父::句柄($request,$next);
}
}

默认情况下,PHPUnit从Laravel站点根目录中的
PHPUnit.xml
文件中提取环境变量。
APP_ENV
变量是控制应用程序环境名称的变量,默认为“testing”。如果您的不同,则需要更改我提供的代码以匹配它。

如果中间件确实存在问题,则可以使用WithoutMiddleware特性将其从测试中排除:

class IndexControllerTest extends TestCase
{
    use Illuminate\Foundation\Testing\WithoutMiddleware;
    ...

你在运行什么版本的Laravel?
class IndexControllerTest extends TestCase
{
    use Illuminate\Foundation\Testing\WithoutMiddleware;
    ...