Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Dusk Mocking Laravel Package

noeldemartin/laravel-dusk-mocking

Laravel Dusk Mocking lets you mock classes and services inside Laravel Dusk browser tests, where ordinary mocks can't reach the separate browser process. Register mocks in your test and have them applied in the application, making end-to-end tests faster and more predictable.

View on GitHub
Deep Wiki
Context7

Getting Started

v6.5.3 is a patch release — additive only, no breaking changes, no migrations, no config republish. Bump the constraint (composer update vendor/package) and you're done; the only new surface area is the testing fake.

Where to look first: the new fake() entry point on the package's facade (it wraps Laravel's Illuminate\Support\Facades\Http::fake() under the hood), then the package's own tests/ directory for canonical usage. Because it delegates to the framework, everything you already know about Http::fake() / Http::assertSent() applies — the package fake just pre-wires the base URL, auth headers, and (usually) sensible default stubs so you don't have to hand-roll them.

First use case: a feature test for a controller that calls the third-party API. Before this release you either hit the network, mocked the package's client class, or copy-pasted Http::fake() arrays with the right base URL.

use Illuminate\Support\Facades\Http;
use Vendor\Package\Facades\Package;

it('creates a record on the remote service', function () {
    Package::fake([
        'api.example.com/v1/records' => Http::response(['id' => 'rec_123'], 201),
    ]);

    $this->post('/records', ['name' => 'Acme'])->assertRedirect('/records');

    Http::assertSent(fn ($request) =>
        $request->url() === 'https://api.example.com/v1/records'
        && $request['name'] === 'Acme'
    );
});

If the package ships default stubs, a bare Package::fake() is often enough to get a suite green — start there, then override only the endpoints whose payloads your assertions care about.

Implementation Patterns

Fake once per test class, override per test. Put the fake in setUp() (or Pest's beforeEach) so every test in the file is hermetic, then pass a URL map in individual tests for the cases that need a specific status or body. The last call wins, so a per-test Package::fake([...]) cleanly supersedes the class-level one.

Cover the base URL, not the whole URL. Matching is Str::is() against the full URL including the query string. Use 'api.example.com/v1/*' rather than pinning exact query strings that will drift.

Sequenced responses for retry/backoff flows. If the package retries on 5xx, Http::fakeSequence() exercises the recovery path deterministically:

Http::fakeSequence()
    ->push(['error' => 'rate limited'], 429)
    ->push(['id' => 'rec_123'], 201);

Package::client()->create(['name' => 'Acme']);

Http::assertSentCount(2);

Assert at the HTTP boundary, not on the package. Http::assertSent, assertNotSent, assertNothingSent, and Http::recorded() give you the outgoing Illuminate\Http\Client\Request — URL, method, headers, and decoded body. That's more durable than asserting against internal package classes, which move between minors.

Test jobs and commands the same way. Queue::fake() and Package::fake() compose fine — just remember to Queue::assertPushed() and run the job (or use Bus::fake() + Bus::assertDispatched) if you want the outgoing HTTP assertion to fire.

Queue::fake();
Package::fake();

$this->post('/records', ['name' => 'Acme']);

Queue::assertPushed(SyncRecord::class);

Fail loudly in CI. Add Http::preventStrayRequests() to your base TestCase::setUp(). Any package call that isn't covered by a fake throws instead of silently hitting a sandbox — this is what turns "the fake is wired up" from a convention into a guarantee.

Keep a live path for local/staging. Fakes belong in tests only. For manual verification, point the package at a sandbox base URL via env/config rather than faking inside app code.

Gotchas and Tips

  • Fake leakage. Laravel clears resolved facades between tests, so Package::fake() does not bleed across test methods — unless you override setUp()/tearDown() without calling parent::, or set the fake in a bootstrap/beforeAll hook (PHPUnit setUpBeforeClass, Pest beforeAll). If you see "unexpected request" failures in a later test, that's the cause.
  • Ordering matters with preventStrayRequests(). Call Package::fake() / Http::fake() after (or in the same setup step as) preventStrayRequests(). A stray-prevention call placed after the fake can mask which requests were actually unmatched.
  • Fakes are synchronous and instant. Latency, timeouts, and connection resets are not simulated. For timeout handling use a closure that throws Illuminate\Http\Client\ConnectionException (or Http::failedConnection() on newer Laravel) — don't assume the fake exercises your retry/timeout branches for free.
  • The assertion callback receives a raw Request, not your DTO. JSON bodies are decoded, so $request['name'] works — but nested payloads may differ from what the package sends after transformation. dd(Http::recorded()) is the fastest way to see the real shape.
  • Caching layers sit above the fake. If the package caches responses (many integrations do), a second call inside the same test may never reach the fake and assertSentCount(1) will look wrong. Flush the relevant cache key in setUp() or disable caching in the test config.
  • Pest datasets share beforeEach state. A fake defined in beforeEach is re-applied per dataset case, which is what you want — but closures capturing $this can pin stale per-case values. Prefer explicit Package::fake([...]) inside the test body for parameterised cases.
  • Parallel testing (--parallel) is safe — each process has its own facade instance and its own fake state. No extra guarding needed.
  • Debugging failures. When assertSent fails, Laravel dumps the recorded requests; if the output is truncated, Http::recorded() returns the full [Request, Response] pairs. Reach for that before reaching for ray()/dump().
  • Extension points worth knowing. URL-keyed arrays for breadth, closure-based fakes when you need to branch on the incoming request, and Http::fake([...]) alongside Package::fake() when the package calls a second host you also need to stub. Mixing the two is fine — the framework-level fake and the package fake target the same underlying factory.
  • Pin the minor. ^6.5 is safe for this release, but the fake's default stubs are now part of your test contract; a future minor could change them. Review the 6.x changelog before bumping, and prefer explicit stubs over relying on defaults for anything you assert on.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console