当有其他参数

时间:2018-04-19 09:10:01

标签: php laravel phpunit

我正在使用Laravel的browserkit测试来测试我的应用中的路线。

路线定义为:

web.php

Route::post("myroute/{mymodel}", "MyController@viewMyModel");

RouteServiceProvider

Route::model("mymodel", MyModel::class); 

myController的

public function viewMyModel(Request $req, MyModel $myModel, $parameter) {
   //Does things
}

我现在需要测试给定MyModel的特定实例的行为

我的测试用例是:

public function testDoesThingsWithoutFailing() {
    $this->withoutMiddleware();
    $this->app->instance(MyModel::class, $this->getMockBuilder(MyModel::class)->getMock());        
    $urlToVisit = url()->action("ReportsController@saveComponentAs", [
        "mymodel" => 123, "parameter" => "p"
    ]);
    $this->call("POST", $urlToVisit);
    $this->assertResponseStatus(200);
}

当我这样做时,由于" mymodel"作为控制器的3参数传递,因为第二个是从容器中注入的,即当我在func_get_argsviewMyModel时,我得到:

array:4 [
0 => Illuminate\Http\Request ...
1 => Mock_MyModel_6639c39c {...}
2 => "123"
3 => "p"
]

这是错误的(但是预期的),因为现在注入参数2而不是被路径绑定替换。

然而,当我尝试

$urlToVisit = url()->action("ReportsController@saveComponentAs", [
     "parameter" => "p"
]);

我得到了

  

UrlGenerationException:缺少[Route:]

所需的参数

在一个理想的世界中,我不需要使用$this->withoutMiddleware(),但我现在需要这样做,因为看起来如果我没有正常解决模型而不是通过容器解决。< / p>

我在这里做错了吗?我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:0)

https://stackoverflow.com/a/46364768/487813的答案使我找到了正确的解决方案。

问题:

我禁用了禁用路由绑定的中间件,这是故意的,因为我认为我需要这个。然而,这使得框架注入模型而不是用模型替换参数。在所有注入的模型之后,参数最终被添加到请求中。

解决方案:

继续使用模型绑定,但模拟绑定结果。这是有效的:

public function testDoesThingsWithoutFailing() {
    // Need the middleware to run
    $this->app->get('router')->bind(MyModel::class, function () { 
         return $this->getMockBuilder(MyModel::class)->getMock(); 
    }); 
    $urlToVisit = url()->action("ReportsController@saveComponentAs", [
        "mymodel" => 123, "parameter" => "p"
    ]);
    $this->call("POST", $urlToVisit);
    $this->assertResponseStatus(200); //Works as expected
}