Laravel 5.2 PUT / PATCH 请求的代码接收功能测试问题
Laravel 5.2 Codeception functional test issue with PUT / PATCH requests
我在 Codeception 的功能测试中处理更新处理时遇到问题:我系统地遇到 404 错误。详情如下。
对于所有其他模拟的 http 请求,一切都进展顺利,但是当 codeception 尝试对 put HTTP 请求执行更新方法时(POST 请求的“_method”参数值为 "PUT" ) 永远不会被我的控制器执行,这会导致更新 url 上的代码接收,而不会在此更新方法中进行处理后发生重定向。我尝试在我的更新方法之上重定向到我的主页以测试该事实,但重定向从未发生。
有关信息,我使用 Laravel5 模块。这是我的 functional.suite.yml 文件内容:
class_name: FunctionalTester
modules:
enabled:
- Asserts
- \Helper\Functional
- MailCatcher
- Laravel5:
environment_file: .env.testing
config:
MailCatcher:
url: 'http://192.168.10.10'
port: '1080'
我尝试将“_method”参数的 "PUT" 值替换为 "PATCH" 以查看是否可以看到任何更改,但问题仍然存在并且行为仍然相同。
Codeception 包括 Laravel5 应用来测试它。我唯一的线索是测试环境无法解释 PUT 或 PATCH 请求。简单的POST请求没有问题(创建不会造成任何问题)。
我确定 HTML 形式是正确的,更新在我的本地环境中正确发生并且 http 请求包含正确的参数。这是我使用 --debug 选项执行它时所拥有的:
[Uri] http://project/en/permissions/update
[Method] POST
[Parameters] {"_token":"RUx7DjU3b6GEjodnpwXvJJYJIcmQJGbabj23q0yK","_method":"PATCH","_id":"1","name_en":"Administrator","name_fr":"Administrateur","slug":"admin"}
[Page] http://project/en/permissions/update
[Response] 200
[Request Cookies] {"XSRF-TOKEN":"eyJpdiI6InZQV2NVcTRoZHVONXYzZzNLTnBWU1E9PSIsInZhbHVlIjoiWWhWa0kyUGxJNkJRTXIyaEhVcDdHR0tRcklHZStpVWdlTjlDdmRKVmEyVDFPWkxBVmhLc1lra05zeWh1ZWtKMENCc29lWFZTN2lSd3dIbjZyNEo5eWc9PSIsIm1hYyI6ImEzMDNmOWM5OGQzNzE4ZWI5MDg0MTI0ZmQwMTI1ZTk0OTM1OTY4NjA5ZTZjMGFhYTI0MTdlMzMzM2QyMWQ4MzUifQ==","laravel_session":"eyJpdiI6ImF4cVFYYVNUU3J0WUd2VzNRZlhSc3c9PSIsInZhbHVlIjoibDdPd3ZEZVZOdDJwRlBjMVZtc2dNM0I3WUw0REEzK25NVFVWT1FIRjEzR05tRGZLXC9SYUZkRmhEdXlyQVdybURHTWVQVUtucnBkZEwwaTN4NWF6XC9YQT09IiwibWFjIjoiMzliODY4ZWUwYmZjODI1OTVkMTBiYjA4ODY2OWNiODc3ZTI1NzAzZmJhMjg4OTY4Y2MzM2VkMjYyYTkwOTQ2MyJ9"}
[Response Headers] {"cache-control":["no-cache"],"Set-Cookie":[{},{}]}
如您所见,该过程以 200 响应结束,仅此而已。我测试了几页,问题到处都是一样的。
我在这个问题上被封锁了数周,但仍未找到任何解决方案。如果有人有线索,我在听!
编辑 1:26/01/2015
正如有人问我的那样,这是我的路线文件。
如您所见,我使用的是 LaravelLocalization,这是一个多语言应用程序。
我只给你展示了权限路由,但它们都是这样管理的。
Route::group([
'prefix' => LaravelLocalization::setLocale(),
'middleware' => [
'auth',
'localize',
'localeSessionRedirect',
'localizationRedirect',
]], function () {
// permissions
Route::get(LaravelLocalization::transRoute('routes.permissions.index'), ['as' => 'permissions.index', 'uses' => 'User\PermissionsController@index']);
Route::get(LaravelLocalization::transRoute('routes.permissions.create'), ['as' => 'permissions.create', 'uses' => 'User\PermissionsController@create']);
Route::post(LaravelLocalization::transRoute('routes.permissions.store'), ['as' => 'permissions.store', 'uses' => 'User\PermissionsController@store']);
Route::get(LaravelLocalization::transRoute('routes.permissions.edit'), ['as' => 'permissions.edit', 'uses' => 'User\PermissionsController@edit']);
Route::put(LaravelLocalization::transRoute('routes.permissions.update'), ['as' => 'permissions.update', 'uses' => 'User\PermissionsController@update']);
Route::delete(LaravelLocalization::transRoute('routes.permissions.destroy'), ['as' => 'permissions.destroy', 'uses' => 'User\PermissionsController@destroy']);
});
编辑 2:29/01/2015
按照 Lerzenit 解决方案解释 ,我尝试将以下代码放入文件 tests/_bootstrap.php :
Request::enableHttpMethodParameterOverride();
它没有效果,我仍然有一个 200 响应,并且从未到达我的控制器的更新方法。
我检查了 $httpMethodParameterOverride
参数是否在方法执行后立即传递给 true
并且可以验证是否已成功设置为 true
.
我还在寻找解决方案。
编辑 3:2015 年 2 月 5 日
我有一个关于调查方式的线索:我成功地对一个名为 'District' 的实体执行了更新,这是我项目中唯一一个以英语和法语使用相同路线的实体。正如我之前指定的,我使用 LaravelLocalization
插件,路由转换可能是 _method
参数错误解释的原因, PUT
值应该重定向到更新方法我的控制器。
如果有人能帮助我,我将不胜感激。
我终于找到了解决办法!
从未达到更新方法,因为在我的 POST 请求中,我有时会通过使用隐藏变量将资源 ID 传递到请求中,例如 _id
。
Laravel 期望在 post UPDATE
或 DELETE
请求中在斜杠后给出一个 id,这就是为什么从未达到 UPDATE / DELETE 方法的原因.事实上,在 PUT / PATCH / DELETE 请求中传递参数是一种不好的做法,因为目标资源必须在 url.
中显式显示
因此,如果您遇到同样的问题,请确保您在表单中精确填写了正确的 POST 路线,例如 route('users.update', ['id' => $user->id])
。
Pfiuuu,我现在可以编写测试以获得 100% 测试的应用程序。那是一次痛苦的调查 ;)
我在 Codeception 的功能测试中处理更新处理时遇到问题:我系统地遇到 404 错误。详情如下。
对于所有其他模拟的 http 请求,一切都进展顺利,但是当 codeception 尝试对 put HTTP 请求执行更新方法时(POST 请求的“_method”参数值为 "PUT" ) 永远不会被我的控制器执行,这会导致更新 url 上的代码接收,而不会在此更新方法中进行处理后发生重定向。我尝试在我的更新方法之上重定向到我的主页以测试该事实,但重定向从未发生。
有关信息,我使用 Laravel5 模块。这是我的 functional.suite.yml 文件内容:
class_name: FunctionalTester
modules:
enabled:
- Asserts
- \Helper\Functional
- MailCatcher
- Laravel5:
environment_file: .env.testing
config:
MailCatcher:
url: 'http://192.168.10.10'
port: '1080'
我尝试将“_method”参数的 "PUT" 值替换为 "PATCH" 以查看是否可以看到任何更改,但问题仍然存在并且行为仍然相同。
Codeception 包括 Laravel5 应用来测试它。我唯一的线索是测试环境无法解释 PUT 或 PATCH 请求。简单的POST请求没有问题(创建不会造成任何问题)。
我确定 HTML 形式是正确的,更新在我的本地环境中正确发生并且 http 请求包含正确的参数。这是我使用 --debug 选项执行它时所拥有的:
[Uri] http://project/en/permissions/update
[Method] POST
[Parameters] {"_token":"RUx7DjU3b6GEjodnpwXvJJYJIcmQJGbabj23q0yK","_method":"PATCH","_id":"1","name_en":"Administrator","name_fr":"Administrateur","slug":"admin"}
[Page] http://project/en/permissions/update
[Response] 200
[Request Cookies] {"XSRF-TOKEN":"eyJpdiI6InZQV2NVcTRoZHVONXYzZzNLTnBWU1E9PSIsInZhbHVlIjoiWWhWa0kyUGxJNkJRTXIyaEhVcDdHR0tRcklHZStpVWdlTjlDdmRKVmEyVDFPWkxBVmhLc1lra05zeWh1ZWtKMENCc29lWFZTN2lSd3dIbjZyNEo5eWc9PSIsIm1hYyI6ImEzMDNmOWM5OGQzNzE4ZWI5MDg0MTI0ZmQwMTI1ZTk0OTM1OTY4NjA5ZTZjMGFhYTI0MTdlMzMzM2QyMWQ4MzUifQ==","laravel_session":"eyJpdiI6ImF4cVFYYVNUU3J0WUd2VzNRZlhSc3c9PSIsInZhbHVlIjoibDdPd3ZEZVZOdDJwRlBjMVZtc2dNM0I3WUw0REEzK25NVFVWT1FIRjEzR05tRGZLXC9SYUZkRmhEdXlyQVdybURHTWVQVUtucnBkZEwwaTN4NWF6XC9YQT09IiwibWFjIjoiMzliODY4ZWUwYmZjODI1OTVkMTBiYjA4ODY2OWNiODc3ZTI1NzAzZmJhMjg4OTY4Y2MzM2VkMjYyYTkwOTQ2MyJ9"}
[Response Headers] {"cache-control":["no-cache"],"Set-Cookie":[{},{}]}
如您所见,该过程以 200 响应结束,仅此而已。我测试了几页,问题到处都是一样的。
我在这个问题上被封锁了数周,但仍未找到任何解决方案。如果有人有线索,我在听!
编辑 1:26/01/2015
正如有人问我的那样,这是我的路线文件。
如您所见,我使用的是 LaravelLocalization,这是一个多语言应用程序。
我只给你展示了权限路由,但它们都是这样管理的。
Route::group([
'prefix' => LaravelLocalization::setLocale(),
'middleware' => [
'auth',
'localize',
'localeSessionRedirect',
'localizationRedirect',
]], function () {
// permissions
Route::get(LaravelLocalization::transRoute('routes.permissions.index'), ['as' => 'permissions.index', 'uses' => 'User\PermissionsController@index']);
Route::get(LaravelLocalization::transRoute('routes.permissions.create'), ['as' => 'permissions.create', 'uses' => 'User\PermissionsController@create']);
Route::post(LaravelLocalization::transRoute('routes.permissions.store'), ['as' => 'permissions.store', 'uses' => 'User\PermissionsController@store']);
Route::get(LaravelLocalization::transRoute('routes.permissions.edit'), ['as' => 'permissions.edit', 'uses' => 'User\PermissionsController@edit']);
Route::put(LaravelLocalization::transRoute('routes.permissions.update'), ['as' => 'permissions.update', 'uses' => 'User\PermissionsController@update']);
Route::delete(LaravelLocalization::transRoute('routes.permissions.destroy'), ['as' => 'permissions.destroy', 'uses' => 'User\PermissionsController@destroy']);
});
编辑 2:29/01/2015
按照 Lerzenit 解决方案解释
Request::enableHttpMethodParameterOverride();
它没有效果,我仍然有一个 200 响应,并且从未到达我的控制器的更新方法。
我检查了 $httpMethodParameterOverride
参数是否在方法执行后立即传递给 true
并且可以验证是否已成功设置为 true
.
我还在寻找解决方案。
编辑 3:2015 年 2 月 5 日
我有一个关于调查方式的线索:我成功地对一个名为 'District' 的实体执行了更新,这是我项目中唯一一个以英语和法语使用相同路线的实体。正如我之前指定的,我使用 LaravelLocalization
插件,路由转换可能是 _method
参数错误解释的原因, PUT
值应该重定向到更新方法我的控制器。
如果有人能帮助我,我将不胜感激。
我终于找到了解决办法!
从未达到更新方法,因为在我的 POST 请求中,我有时会通过使用隐藏变量将资源 ID 传递到请求中,例如 _id
。
Laravel 期望在 post UPDATE
或 DELETE
请求中在斜杠后给出一个 id,这就是为什么从未达到 UPDATE / DELETE 方法的原因.事实上,在 PUT / PATCH / DELETE 请求中传递参数是一种不好的做法,因为目标资源必须在 url.
因此,如果您遇到同样的问题,请确保您在表单中精确填写了正确的 POST 路线,例如 route('users.update', ['id' => $user->id])
。
Pfiuuu,我现在可以编写测试以获得 100% 测试的应用程序。那是一次痛苦的调查 ;)