Search code examples
laravelphpunitmockery

Trouble faking a Laravel HttpClient response


I am trying to test the following bit of code:

enter image description here

DimonaClient is just a simple wrapper around a Laravel HttpClient; simplified function here:

enter image description here

The getDeclaration() response is a \Illuminate\Http\Client\Response


What I am trying to do in my test is:

  1. Mock the DimonaClient class so I don't create an actual api call
  2. "Mock" (use Laravel's Http::response()) the response I want so that I can test that a 200 w/ certain statuses dispatches the appropriate event (also mocked, but not relevant here)

My test code looks like this:

enter image description here

My issue(s) seem to be:

  1. the getDeclaration() has an expectation of Illuminate\Http\Client\Response but I can't seem to create anything that will satisfy that (a new Response wants a MessageInterface, etc, etc... )
  2. I don't actually need getDeclaration() to return anything for my testing, so I wonder if I should be mocking this differently in any case (I base this assumption on Http::response handling the internal code I'm testing for things like $response->ok(), instead of a Mockery expectation)

I feel like I'm one small step away from making this work, but going round in circles trying to hook it up correctly.

TIA!


Solution

  • If you are using Http Facade, you don't need to mock DimonaCient. You are nearly there with your test, but let me show you what you would have done:

    /** @test */
    public function it_can_handle_an_approved_submission(): void
    {
        Http::fake([
            '*' => Http::response([
                'declarationStatus' => [
                    'result' => DimonaDeclarationStatus::ACCEPTED,
                    'dimonaPeriodId' => $this->faker->numerify('############'),
                ],
            ],
        ]);
    
        $dimonaDeclarationId = $this->faker->numerify('############');
    
        // Do your normal call, and then assertions
    }
    

    Doing this, you will tell Http to fake any URL, because we are using *. I would recommend you use $this->endpoint/$declarationId so if it does not match, you will also know you did not hit the right endpoint.


    I am not sure what Laravel you are using but this is available since Laravel 6+, check Http fake URLs.