0

I created an helper class that wraps http calls to an external service using the Http facade: all the methods basically wraps the same http call structure: Http::withHeaders()->post() or get() using the right headers, target url and data.
Now I need to mock it during tests to avoid having it making real calls.

Since I do not need to mock the withHeaders method I just want to mock the post/get method so I came up to this:

Http::fake(); Http::partialMock() ->makePartial() ->shouldDeferMissing(); Http::shouldReceive('post') ->with($this->defaultData) ->once() ->andReturn('tests'); 

but when running the test it breaks beacuse curl is trying to make a real call:

cURL error 6: Could not resolve host: fake-test-host (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for fake-test-host/api/private/v1/target 

Also, removing the second code block (the one with partialMock) it seems partially working since the error change in

Method Mockery_2_Illuminate_Http_Client_Factory::withHeaders() does not exist on this mock object 

as if the post method where been mocked but withHeaders did not.

1

1 Answer 1

2

You can mock HTTP calls in Laravel using the Http::fake() method. This lets you prevent real HTTP requests from being sent during tests.

To fake a specific endpoint:

Http::fake([ 'fake-test-host/api/private/v1/target' => Http::response('tests', 200), ]); 

To fake all POST requests and return a test response:

Http::fake(function ($request) { if ($request->method() === 'POST') { return Http::response('tests', 200); } return Http::response('Not Found', 404); }); 

To assert that a request was sent to a specific URL:

Http::fake(); YourHelper::callTheThing(); Http::assertSent(function ($request) { return $request->url() === 'https://fake-test-host/api/private/v1/target' && $request->method() === 'POST'; }); 

You don't need to use partialMock() or shouldDeferMissing() when working with the Http facade.

Sign up to request clarification or add additional context in comments.

2 Comments

It works, but if that is the proper way to create a partial mock why do the facade have methods like the ones I used? What's the point with those?
@fudo Those methods are mostly there for when you create your own facades. Let’s say you have a class with a bunch of methods, and you only want to fake one during testing — that’s when you use partialMock(), makePartial(), and shouldDeferMissing() to keep the rest working as usual. But with Laravel’s Http facade, Http::fake() already handles everything by replacing the HTTP client. So mixing in partial mocks with Http just causes weird issues. They’re useful, just not in this case.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.