Summer Sale! All accounts are 50% off this week.

sandersjj's avatar

Failed asserting that exception of type "\Exception" is thrown.

Hi,

I am running Laravel 5.8.27 and phpunit 7.5.13.

I have this test:

  /**
     * @test
     * @expectedException \Exception
     */
    public function an_exception_will_be_thrown_if_unknown_enum_is_requested()
    {
        $this->withExceptionHandling();
        $this->getJson('/api/enums/nonexistingenum');


    }

In my controller function I throw the exception right away:

public function show($enum)

    { 
   throw new \Exception('sfdsfd');
 }

However I get this error when running the test:

Failed asserting that exception of type "\Exception" is thrown.

Any suggestions?

0 likes
19 replies
mstrauss's avatar

Not sure if this is just a mock up or your actual code, but Exception is spelled wrong:

current

 throw new \Exeption('sfdsfd');

Should be

 throw new \Exception('sfdsfd');
sandersjj's avatar

@mstrauss sharp one however this wasn't the issue. I fixed the start post. Still getting the same error

mstrauss's avatar

Oh wait, I think I see the problem:

Might be this line

* @expectedException \Exception

Try changing it to the actual exception type you expect:

* @expectedException InvalidArgumentException

And update this as well:


public function show($enum)

 { 
   
     throw new InvalidArgumentException('The enum is invalid ');
 }

Also, $this->withExceptionHandling(); is on by default. So you typically don't need to explicitly state that.

But that feels pretty contrived. How does the application handle it for real when an invalid enum URL is hit? Check and then use that as the exception type in your test. Because you're probably not going to keep throwing the exception immediately on the show method and the test should match what the actual app does. Just a suggestion.

sandersjj's avatar

If I do a dd of $this->getJson('/api/enums/nonexistingenum') then I get:

Illuminate\Foundation\Testing\TestResponse {#347
  +baseResponse: Illuminate\Http\JsonResponse {#419
    #data: """
      {\n
          "message": "sfdsfd",\n
          "exception": "Exception",\n
          "file": "/home/vagrant/code/kasjroet/app/Http/Controllers/EnumsController.php",\n
...
bobbybouwmann's avatar

@dubbeltje That is correct right? You throw that exception yourself in the code.

What happens when you try this in code?

/**
 * @test
 */
public function an_exception_will_be_thrown_if_unknown_enum_is_requested()
{
    $this->expectException(\Exception::class);

    $this->getJson('/api/enums/nonexistingenum');
}
2 likes
mstrauss's avatar

Sorry, @dubbeltje, I was asking if you hit that endpoint, without throwing the error in the controller, what happens?

sandersjj's avatar

It does hit the endpoint because I have got already one test which hits the endpoint and gives good results. It's just the one with the exception which I can't get working.

mstrauss's avatar

Got you. If you comment out the exception:

public function show($enum)

    { 
   // throw new \Exception('sfdsfd');
 }

And tried the below:

dd($this->getJson('/api/enums/nonexistingenum')); 

What's the output?

sandersjj's avatar
Illuminate\Foundation\Testing\TestResponse {#328
  +baseResponse: Illuminate\Http\Response {#398
    +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag {#403
      #computedCacheControl: array:2 [
        "no-cache" => true
        "private" => true
      ]
      #cookies: []
      #headerNames: array:5 [
        "cache-control" => "Cache-Control"
        "date" => "Date"
        "content-type" => "Content-Type"
        "x-ratelimit-limit" => "X-RateLimit-Limit"
        "x-ratelimit-remaining" => "X-RateLimit-Remaining"
      ]
      #headers: array:5 [
        "cache-control" => array:1 [
          0 => "no-cache, private"
        ]
        "date" => array:1 [
          0 => "Mon, 08 Jul 2019 19:40:51 GMT"
        ]
(...)

1 like
sandersjj's avatar

@bobbybouwmann

When I do this:

/**
     * @test
     */
    public function an_exception_will_be_thrown_if_unknown_enum_is_requested()
    {
        $this->expectException(\Exeption::class);
        $this->getJson('/api/enums/nonexistingenum');

    }


public function show($enum)
 {
       throw new \Exception('sfdsfd');
     
 }

I get the response:

Failed asserting that exception of type "Exeption" is thrown.

mstrauss's avatar

Just double checking the spelling again on your previous post:

current:

/**
     * @test
     */
    public function an_exception_will_be_thrown_if_unknown_enum_is_requested()
    {
        $this->expectException(\Exeption::class);
        $this->getJson('/api/enums/nonexistingenum');

    }

probably should be:

/**
     * @test
     */
    public function an_exception_will_be_thrown_if_unknown_enum_is_requested()
    {
        $this->expectException(\Exception::class);
        $this->getJson('/api/enums/nonexistingenum');

    }

And that matters, because the Exeption class does not exist. Probably just a typo, but I wanted to be sure.

sandersjj's avatar

Correct. But it still throws the same error: 'Failed asserting that exception of type "Exception" is thrown.'

roerjo's avatar
<?php

namespace Tests\Unit;

use Tests\TestCase;

class ExceptionTest extends TestCase
{
    /** @test */
    function test_exception()
    {
        $this->expectException(\Exception::class);

        throw new \Exception('blah');
    }
}

This test passes for me so there must be something else you haven't shown us.

1 like
siangboon's avatar

will it something wrong with your '/api/enums/nonexistingenum' file? how is the code look like?

sandersjj's avatar

@siangboon the last part of the uri is a parameter. The code in the function looks like this:

<?php

namespace App\Http\Controllers;

use Exception;

class EnumsController extends Controller
{
    public function show($enum)
    {


        $classname = 'App\Enums\' . ucfirst($enum);
        if (!class_exists($classname)) {
            throw new Exception('sfd');
        }
        return response()->json($classname::values(), 200);
    }
}

The route file looks like this:

Route::get('/enums/{enum}', 'EnumsController@show');

Even when properly importing \Exception I get the same error:

Failed asserting that exception of type "Exception" is thrown.

This is the test I am trying to run.

   /**
     * @test
     */
    public function an_exception_will_be_thrown_if_unknown_enum_is_requested()
    {
        $this->expectException(Exception::class);
        $this->get('/api/enums/nonexistingenum');

    }
siangboon's avatar

i think the expectException is expecting a valid and specify type of exception class like:

$this->expectException(InvalidArgumentException::class);

atorscho's avatar

In case someone else has the same problem, I just found out that adding $this->withoutExceptionHandling() call just before resolves this issue:

$this->withoutExceptionHandling();
$this->expectException(InvoiceNotFoundException::class);

$this->getJson('/invoices/9999/items');
6 likes
atunje's avatar

This works for me.

The issue is that the test environment is automatically catching / handling exceptions.

Therefore, any exception thrown when a request is made to an endpoint will be caught already.

So, $this->withoutExceptionHandling(); disables this exception handling.

1 like

Please or to participate in this conversation.