I want to test the response when I try to send invalid data to the API.
/** @test */
public function request_schedule_with_invalid_bdate()
{
$response = $this->json('GET', '/api/schedule', [
'bdate' => 'thisaintadate',
]);
$response->assertStatus(422);
}
According to the documentation it should return a 422
If the validation rules pass, your code will keep executing normally; however, if validation fails, an exception will be thrown and the proper error response will automatically be sent back to the user. In the case of a traditional HTTP request, a redirect response will be generated, while a JSON response will be sent for AJAX requests.
Also,
When using the validate method during an AJAX request, Laravel ... generates a JSON response containing all of the validation errors. This JSON response will be sent with a 422 HTTP status code.
It sounds like Laravel should automatically handle the exception thrown and proceed with sending the response.
However, running this in PHPUnit would just cause an error.
There was 1 error:
1) Tests\Feature\ScheduleTest::request_schedule_with_invalid_bdate
Illuminate\Validation\ValidationException: The given data was invalid.
I read this question but using $this->expectException(...);
will make the test pass but not run my assertions. If I assert the status to be something else other than 422, it will still pass.
My controller has this:
public function show(Request $request)
{
$attributes = $request->validate([
'bdate' => 'required|date'
]);
return ['data' => "It's valid."]
}
Here is my ExceptionHandler class (as requested by Martin H.) This is just what's out of the box. I haven't touched this class yet.
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Report or log an exception.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $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)
{
return parent::render($request, $exception);
}
}
I have confirmed the following:
- Laravel Framework 5.7.21 (
php artisan --version
output) It runs the appropriate code/controller based on the stack trace:
.../vendor/laravel/framework/src/Illuminate/Validation/Validator.php:315 .../vendor/laravel/framework/src/Illuminate/Validation/Factory.php:136 .../vendor/laravel/framework/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php:53 .../vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php:108 .../app/Http/Controllers/MyController.php:35
What am I missing?