使用JSON请求的Laravel / phpunit测试会丢失重要的请求详细信息

时间:2018-04-16 11:34:19

标签: laravel phpunit lumen laravel-passport

我有一个简单的测试,我想断言一个特定的JSON响应。测试(修剪)看起来像这样:

$response = $this->json('POST', '/api/auth/register', [
        'client_id' => $client->id,
        'client_secret' => $client->secret
    ]);

$response->assertStatus(422);

$response->assertJson([
        'error' => 'validation_error',
        'message' => 'There were validation errors with the form input.'
    ]);

非常基本的东西。出现问题的地方是,在我的应用程序中,我有一个开关,它根据URL有条件地加载不同的异常处理程序。这看起来像这样:

if(request()->is('api/*')) {
    return new Optimus\Heimdal\ExceptionHandler($app);
}

如果我用curl或postman运行请求,没问题。但是,在PHP单元中它并没有在路径上捡起来,就像路径没有被传递一样。为了解决此问题,我使用wantsJson()检查替换了此路径检查,但这也无效。

这似乎与此https://github.com/laravel/lumen-framework/issues/55有关 - 我还没有得出解决方案!

我想至少更好地理解这一点。一个合适的解决方案是可取的,否则我可以看到一个肮脏的黑客,未来我可能会忘记!

任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

我不完全理解为什么此时无法提供请求的原因,但是使用两个处理程序的一种更可靠的方法是将应用程序的异常处理程序绑定到优化程序,而不是在它们之间进行交换。

该请求已传递到render中,并且report可能仍应报告所有内容。

我使用$app->runningInConsole()时遇到的问题是,它将导致测试中对Web异常的不同处理-例如通常会捕获未经身​​份验证的异常以触发通过Web而非api重定向。

/**
 * Create a new exception handler instance.
 *
 * @param  \Illuminate\Contracts\Container\Container  $container
 * @return void
 */
public function __construct(Container $container)
{
    parent::__construct($container);

    $this->heimdal = new \Optimus\Heimdal\ExceptionHandler($container);
}

/**
 * Report or log an exception.
 *
 * This is a great spot to send exceptions to Sentry, Bugsnag, etc.
 *
 * @param  \Exception  $exception
 * @return void
 */
public function report(Exception $exception)
{
    $this->heimdal->report($exception);

    parent::report($exception);
}

/**
 * Render an exception into an HTTP response.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Exception  $exception
 * @return \Illuminate\Http\Response
 */
public function render($request, Exception $exception)
{
    if ($request->is('api/*')) {
        return $this->heimdal->render($request, $exception);
    }

    return parent::render($request, $exception);
}

答案 1 :(得分:0)

好的,所以更多的挖掘,它似乎与这个https://laravel-news.com/request-object-changes-in-lumen-5-4

有关

我将条件代码移到相应路径文件中的两个单独的代码块中。这有效,但在这里改变环境感觉很讨厌。我暂时选择的“黑客”是添加支票:

$app->runningInConsole()

这修复了测试。感觉不尽如人意,但如果它被删除,所有的测试都会爆炸,我会抓住它,所以我猜它。