Closed likeadeckofcards closed 7 years ago
Did you actually put the following line in the function your testing?
$this->disableExceptionHandling();
Yes I did. and nothing happened
I think I may have had this issue perhaps.
Have you put it in your TestCase.php file instead of adding it to the specific test file.
protected function disableExceptionHandling()
{
$this->app->instance(ExceptionHandler::class, new class extends Handler {
public function __construct() {}
public function report(Exception $e) {}
public function render($request, Exception $e) {
throw $e;
}
});
}
Here is my TestCase.php file:
<?php
use App\Exceptions\Handler;
use Symfony\Component\Debug\ExceptionHandler;
abstract class TestCase extends Illuminate\Foundation\Testing\TestCase
{
/**
* The base URL to use while testing the application.
*
* @var string
*/
protected $baseUrl = 'http://localhost';
/**
* Creates the application.
*
* @return \Illuminate\Foundation\Application
*/
public function createApplication()
{
$app = require __DIR__.'/../bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();
return $app;
}
protected function disableExceptionHandling()
{
$this->app->instance(ExceptionHandler::class, new class extends Handler {
public function __construct() {}
public function report(Exception $e) {}
public function render($request, Exception $e) {
throw $e;
}
});
}
}
Sample Test (can't remember which one it was originally used on):
/** @test */
function cannot_purchase_more_tickets_than_remain() {
$this->disableExceptionHandling();
$concert = factory(Concert::class)->states('published')->create()->addTickets(50);
$this->orderTickets($concert, [
'email' => 'test@test.com',
'ticket_quantity' => 53,
'payment_token' => 'valid-payment-token',
]);
$this->assertResponseStatus(422);
$this->assertFalse($concert->hasOrderFor('test@test.com'));
$this->assertEquals(0, $this->paymentGateway->totalCharges());
$this->assertEquals(50, $concert->ticketsRemaining());
}
output of running the test (It does run extremely slow...):
C:\Users\medeck\Downloads\php-7.1.0-Win32-VC14-x64\php.exe C:/xampp/htdocs-temp/ticketbeast/vendor/phpunit/phpunit/phpunit --configuration C:\xampp\htdocs-temp\ticketbeast\phpunit.xml --filter "/::cannot_purchase_more_tickets_than_remain( .*)?$/" PurchaseTicketsTest C:\xampp\htdocs-temp\ticketbeast\tests\features\PurchaseTicketsTest.php --teamcity
Testing started at 2:36 PM ...
PHPUnit 5.7.4 by Sebastian Bergmann and contributors.
Time: 1.44 seconds, Memory: 16.00MB
OK (1 test, 4 assertions)
Process finished with exit code 0
The test is running fine if it's says OK. The exception helper is to translate laravel's http status responses into exception's which help you debugging.
It changes this function into
public function render($request, Exception $e) {
throw $e;
}
Yes there were a few tests in the app that when you implemented this function it caused the test to break.
Here is the output when I force the test to break:
C:\Users\medeck\Downloads\php-7.1.0-Win32-VC14-x64\php.exe C:/xampp/htdocs-temp/ticketbeast/vendor/phpunit/phpunit/phpunit --configuration C:\xampp\htdocs-temp\ticketbeast\phpunit.xml --filter "/::cannot_purchase_more_tickets_than_remain( .*)?$/" PurchaseTicketsTest C:\xampp\htdocs-temp\ticketbeast\tests\features\PurchaseTicketsTest.php --teamcity
Testing started at 2:43 PM ...
PHPUnit 5.7.4 by Sebastian Bergmann and contributors.
Expected status code 422, got 500.
Failed asserting that 500 matches expected 422.
Expected :422
Actual :500
<Click to see difference>
C:\xampp\htdocs-temp\ticketbeast\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:744
C:\xampp\htdocs-temp\ticketbeast\tests\features\PurchaseTicketsTest.php:98
Time: 1.45 seconds, Memory: 16.00MB
FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
Process finished with exit code 1
Yes, because some test rely on the exception handler throwing http responses. I will search the course where Adam explains it. @adamwathan explains it in Getting Started with Validation Testing
By default the exception handler will try and change an exception that is thrown to an http response which the browser understand. For example ModelNotFoundException is automatically translated to a 404. But if you are testing your application it can be difficult to debug because the only response phpunit is getting is that 404. Adam's function disables this behaviour, which helps you see the stack trace that is originally thrown.
If you look at the last test I pasted here it shows the response code still being sent back instead of re-throwing the exception like this method is supposed to prevent.
The method is supposed to re-throw (it disables the original method which translates it into http status codes). Try removing $this->disableExceptionHandling(); in the test.
Hey @infernobass7, your problem is you are overriding the wrong Exception Handler.
At the top of your test case file, you have:
use Symfony\Component\Debug\ExceptionHandler;
That should be:
use Illuminate\Contracts\Debug\ExceptionHandler;
Copy the full test case file from here and see if that helps:
https://github.com/nothingworksinc/ticketbeast/blob/master/tests/TestCase.php
Ah, I did not see that sorry! I was thinking that the ValidationException was thrown instead of the actual 422 that you were expecting. Luckily Adam is here to help :)
Thank you, Adam. That was exactly what I was missing!
Ha! This one got me too!
I don't know why but when I tried to implement the disableExceptionHandling function (even by copy the code in this repo to ensure no typos). I still get the response code instead of the actual exception.
Any thoughts or suggestions?
(BTW: Great course so far)