gpt4 book ai didi

php - 在 Laravel 中使用 PHPUnit 测试 HTTP 动词时遇到问题

转载 作者:行者123 更新时间:2023-12-02 05:33:04 25 4
gpt4 key购买 nike

在开始之前,我想说我已经看过 Failed asserting the HTTP status is 200 not 500以及Failed asserting the HTTP status code is 200 not 500 .不要让名字骗了你;他们是2个不同的职位。这两个帖子都超过 9 个月,没有好的答案。

我在测试路线时遇到了一些麻烦。因此,我在运行 OS X Yosemite 10.10.2 的 Mac Mini 上创建了一个新的 Laravel 5 项目。我正在制作一个 API。因此,我首先开始制作 API 的后端部分。我决定要使用 PHPUnit 为该项目实现 TDD。我的 PHPUnit 版本是 4.0.20。我正在运行 PHP 5.5.14 并在 artisan 命令行工具中使用与 Laravel 打包的服务器。

现在,我开始确保我可以连接到服务器。所以,我的第一个测试看起来像:

public function testGetMessagesResponse()
{
$response = $this->call('GET', 'Messages');

$this->assertEquals(200, $response->getStatusCode());
}

这一切顺利。但是,当我转到 POST 请求时,它失败了。这是我的第二个测试的样子:

public function testPostMessagesResponse()
{
$response = $this->call('POST', 'Messages');

$this->assertEquals(200, $response->getStatusCode());
}

这个测试失败了。输出如下所示:

1) MessagesTest::testPostMessagesResponse
Failed asserting that 500 matches expected 200.

在我的 routes.php 文件中,我确实注册了这条路线:

Route::resource('Messages', 'MessagesController');

在我的 MessagesController 中,我拥有所有必需的方法:

<?php namespace App\Http\Controllers;

use App\Http\Requests;
use App\Http\Controllers\Controller;

use Illuminate\Http\Request;

class MessagesController extends Controller {

/**
* Display a listing of the resource.
*
* @return Response
*/
public function index()
{
return 'response';
}

/**
* Show the form for creating a new resource.
*
* @return Response
*/
public function create()
{
return 'response';
}

/**
* Store a newly created resource in storage.
*
* @return Response
*/
public function store()
{
return 'response';
}

/**
* Display the specified resource.
*
* @param int $id
* @return Response
*/
public function show($id)
{
return 'response';
}

/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return Response
*/
public function edit($id)
{
return 'response';
}

/**
* Update the specified resource in storage.
*
* @param int $id
* @return Response
*/
public function update($id)
{
return 'response';
}

/**
* Remove the specified resource from storage.
*
* @param int $id
* @return Response
*/
public function destroy($id)
{
return 'response';
}

}

因此,目前,无论 HTTP 动词如何,我都应该得到 'response'。现在,我决定用 curl 来验证测试:

curl -X POST http://myapp.com/Messages

这会返回 Laravel 的“糟糕!”页。所以确实存在某种服务器错误,但我不确定要寻找什么。应用程序流程看起来不错,但显然行不通。这是我的 Laravel 日志中的堆栈跟踪:

[timestamp] local.ERROR: exception 'Illuminate\Session\TokenMismatchException' in /Users/username/Sites/project/storage/framework/compiled.php:2375
Stack trace:
#0 /Users/username/Sites/project/app/Http/Middleware/VerifyCsrfToken.php(17): Illuminate\Foundation\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#1 /Users/username/Sites/project/storage/framework/compiled.php(8858): App\Http\Middleware\VerifyCsrfToken->handle(Object(Illuminate\Http\Request), Object(Closure))
#2 /Users/username/Sites/project/storage/framework/compiled.php(11990): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#3 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\View\Middleware\ShareErrorsFromSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#4 /Users/username/Sites/project/storage/framework/compiled.php(10696): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#5 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Session\Middleware\StartSession->handle(Object(Illuminate\Http\Request), Object(Closure))
#6 /Users/username/Sites/project/storage/framework/compiled.php(11696): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#7 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse->handle(Object(Illuminate\Http\Request), Object(Closure))
#8 /Users/username/Sites/project/storage/framework/compiled.php(11645): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#9 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Cookie\Middleware\EncryptCookies->handle(Object(Illuminate\Http\Request), Object(Closure))
#10 /Users/username/Sites/project/storage/framework/compiled.php(2411): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#11 /Users/username/Sites/project/storage/framework/compiled.php(8858): Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode->handle(Object(Illuminate\Http\Request), Object(Closure))
#12 [internal function]: Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request))
#13 /Users/username/Sites/project/storage/framework/compiled.php(8849): call_user_func(Object(Closure), Object(Illuminate\Http\Request))
#14 /Users/username/Sites/project/storage/framework/compiled.php(1862): Illuminate\Pipeline\Pipeline->then(Object(Closure))
#15 /Users/username/Sites/project/storage/framework/compiled.php(1852): Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(Object(Illuminate\Http\Request))
#16 /Users/username/Sites/project/public/index.php(53): Illuminate\Foundation\Http\Kernel->handle(Object(Illuminate\Http\Request))
#17 /Users/username/Sites/project/server.php(21): require_once('/Users/username/Site...')
#18 {main}

我是 Laravel 的新手,所以我不确定如何真正深入挖掘并使用堆栈跟踪来找出问题所在。我也曾在没有 Route::resource 的情况下尝试过,但这并没有缓解我的情况。我的 GET 仍然工作正常 (Route::get),但我的 POST (Route::post) 仍然出现相同的 500 错误。 .../compiled.php 中包含第 2375 行的函数(来自堆栈跟踪顶部抛出的异常)由 Laravel 生成,如下所示:

public function handle($request, Closure $next)
{
if ($this->isReading($request) || $this->tokensMatch($request)) {
return $this->addCookieToResponse($request, $next($request));
}
throw new TokenMismatchException();
}

那时,我尝试编辑 POST 测试,因为我实际上并没有发送任何数据。所以这是我修改后的第二个测试:

public function testPostMessagesResponse()
{
$response = $this->call('POST', 'Messages', array("key" => "value"));

$this->assertEquals(200, $response->getStatusCode());
}

我收到相同的错误消息。我觉得我缺少一些简单的东西,但我无法弄清楚。任何帮助将不胜感激。

最佳答案

@Alan Storm:你对正在发生的事情完全正确。我在 Laracasts 上发布了同样的问题,你所描述的问题也反射(reflect)在那里。但是,为了在信用到期时给予信用,我收到了一个更优雅的问题解决方案。所以,我在这里重新发布它,以便其他人遇到同样的问题时也能看到它。来自 Laracasts 的 JarekTkaczyk:

The thing is, that Laravel 5 runs VerifyCsrfToken middleware for each request, no exceptions. It verifies that the request is either read (GET, HEAD, OPTIONS) or has valid token.

In your case there is no valid token, so you get TokenMismatchException. Now, to get rid of the problem you can disable this verification for testing environment.

Simply adjust app/Http/Middleware/VerifyCsrfToken.php to this:

public function handle($request, Closure $next)
{
if ('testing' !== app()->environment())
{
return parent::handle($request, $next);
}

return $next($request);
}

Now, happy testing!

关于php - 在 Laravel 中使用 PHPUnit 测试 HTTP 动词时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28355665/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com