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

Fumocker Laravel Package

fp/fumocker

Fumocker is a lightweight PHP library for mocking function calls in unit tests. It helps you stub built-in or namespaced functions, isolate code from side effects, and write more predictable tests without introducing heavy testing dependencies.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. Fumocker is a test-support utility, not an application dependency, and it has no Laravel integration surface whatsoever — no service provider, no facade, no package auto-discovery, no config file, no artisan command. It would enter the codebase strictly as a require-dev Composer entry invoked from a base TestCase. That is acceptable for a utility, but it means the adoption cost is entirely borne by our test scaffolding, not by a vendor-supported integration path.

More importantly for a Laravel codebase, the addressable problem is already largely solved natively. Laravel ships Carbon::setTestNow() for time, Http::fake() for outbound calls, Storage::fake() and File::fake() for filesystem I/O, Bus/Event/Queue fakes for async boundaries, and Str::createRandomStringsUsing() / Random fakes for randomness in recent versions. Fumocker's value proposition — intercepting bare time(), rand(), file_get_contents(), curl_exec() calls — only bites on code that bypasses Laravel's facades and contracts entirely. In a modern Laravel app that is a narrow slice, usually third-party or copy-pasted legacy classes. Inside a well-structured Laravel app the honest answer is that Fumocker solves a problem we should be refactoring away rather than tooling around.

Integration feasibility. There is a probable hard blocker. The package predates PHP 7; its composer.json targets PHP 5.x. Every currently supported Laravel release requires PHP 7.3 or later, and Laravel 10/11 require PHP 8.1/8.2. Composer will therefore refuse to resolve fp/fumocker on any modern Laravel image. Making it install means forking the package and editing the platform constraint ourselves — at which point we are the maintainer, and the "7 stars, 0 dependents, score 1.08" adoption signal becomes our problem in full. This must be verified in a throwaway branch before any design work is committed to, because the outcome changes the decision from "pilot it" to "fork it or drop it."

Technical risk. High, and concentrated in test-suite reliability rather than production security (there is no production runtime risk — the package never ships). The specific hazards are well-understood for this class of tool: mocks are process-global and leak silently across tests if unregister() is missed; the mechanism only intercepts unqualified function calls in files loaded through the scope, so \time() and already-autoloaded or opcache-served files are unaffected and the mock silently no-ops; double registration can trigger redeclare errors; and the whole thing is at odds with parallel test execution, which Laravel exposes directly via php artisan test --parallel. Silent no-op mocking is the worst failure mode available to a test tool, because it produces green builds that assert nothing.

Key questions.

  • Does it actually install on our PHP version, or does it require a fork? (Verify first; this gates everything.)
  • Which PHP and PHPUnit versions are exercised? Does it work with PHPUnit 10/11, which Laravel 10/11 use?
  • Does it require uopz/runkit, and are those installable in our CI images and containerized local dev?
  • Are mocks reliably restored, and does it behave under Paratest?
  • Who owns patches when PHP or PHPUnit moves? (Answer: we do.)
  • For each candidate test, what is the actual cost of the refactor instead — a Clock interface, an injected HTTP client, a Storage disk?
  • What is our exit criterion and who is accountable for executing it?

Recommendation. Do not adopt. Do not add to an approved testing-utilities list. The combination of a PHP 5.x platform constraint against a PHP 8 Laravel stack, zero dependents, and direct overlap with Laravel's own first-party fakes makes the expected value negative for a standard Laravel engineering org. The only defensible use is a time-boxed, single-suite spike in a genuinely legacy PHP 5.x/7.x codebase outside the main Laravel application, with php-mock/php-mock-phpunit run side-by-side as the control.

Integration Approach

Stack fit. Test-only, and it should stay that way. It must never appear in require, in the production autoloader, or in a runtime container image. Because there is no Laravel service provider, integration means writing our own glue: a FumockerTestCase base class with register() in the test and an unconditional unregister() in tearDown() so cleanup survives assertion failures and exceptions. That wrapper is our code, our maintenance, and the thing most likely to be subtly wrong.

Keep Fumocker usage in a dedicated test suite directory with its own phpunit.xml testsuite entry, excluded from the default parallel run. Do not let register( calls diffuse across the suite — a leaked time() override will surface as a flaky failure on an unrelated branch days later, and the diagnosis cost will far exceed whatever the mock saved.

Migration path. Start from an inventory, not from adoption. Enumerate the tests that genuinely cannot be written today and classify each by root cause: bare global function call, missing DI seam, or third-party library we don't control. Then work the list in preference order — (1) Laravel-native fakes and Carbon::setTestNow, (2) extract a narrow interface (Clock, HttpClient, Randomizer) and inject it, (3) only then consider function-level mocking. In practice most of the inventory will close at step 1 or 2. Fumocker should be framed to engineers explicitly as a migration lever, not a destination: freeze the function, write the test, extract the seam, delete the mock. Track the residual mock count as a debt metric with a target of zero.

Compatibility. Build an explicit matrix before committing: PHP version, PHPUnit version, Laravel version, CI runner image, opcache.enable_cli setting, Paratest behavior, and whether uopz/runkit can be installed. Validate on a disposable CI job, not on the main pipeline. The deciding row is PHP: if the platform constraint does not resolve, stop — we do not hold a Laravel upgrade hostage to a 7-star dev dependency, and forking to relax the constraint is a scope increase that needs its own justification. Verify opcache.enable_cli=0 in the test job, and confirm that classes under test are instantiated after registration so the scoped redefinition actually takes effect.

Sequencing.

  1. Confirm license (MIT), repository liveness, and last commit date.
  2. Attempt composer require --dev fp/fumocker on the current PHP image. Expect failure; record the exact reason.
  3. If it resolves, write one test that mocks time(), asserts business behavior, and asserts restoration.
  4. Re-run repeated and parallel to check for leakage and cross-contamination.
  5. Run the same test with php-mock/php-mock-phpunit and with a Carbon::setTestNow() / Clock refactor. Compare setup friction, readability, and stability.
  6. Decision gate: adopt narrowly only if it beats both alternatives, with a named owner and a written exit criterion.
  7. Otherwise, close the spike, document the finding, and route the work into refactoring backlog.

The gate at step 6 is the deliverable. The most likely good outcome of this evaluation is a one-page "evaluated and rejected, here is why, here is what we did instead" — that is a real artifact, not a failed project.

Operational Impact

Maintenance. Assume we own it. With 7 stars and no dependents there is no realistic upstream maintenance, no security response, and no issue triage. Any upstream commit is unverified until we test it. Budget for exact version pinning, a vendored or forked copy if the PHP constraint must be relaxed, and periodic compatibility re-checks against each PHP/PHPUnit bump. Treat the fork scenario as the expected scenario, not the contingency — and note that a fork means every future Laravel upgrade includes a manual step of re-validating our patched copy of a test utility nobody outside the team has heard of.

Support. No vendor, no support contract, and effectively no documentation beyond the src/ tree and the package's own test fixtures. Internal ownership of troubleshooting lands on platform or QA: CI image extension installation, opcache configuration, parallel-runner exclusions, and the inevitable "why is this assertion silently passing" investigation. Engineers will need explicit guidance on PHP function resolution and namespace fallback, because the unqualified-call-only constraint is the single most common cause of a mock that appears to work and doesn't.

Scaling. Scaling risk is confined to the test suite, not the application — but it is real. Fumocker is the most reliable answer to a small, legacy, sequential test surface and a poor answer to a large one. It pushes toward process isolation, inflates CI wall-clock time, and conflicts with Paratest, which is exactly the lever we pull when the suite gets slow. Narrow, suite-segregated usage scales acceptably; standardization across the suite does not.

Failure modes. Missing PHP extension in a CI image; PHP/PHPUnit/Laravel upgrade incompatibility; composer platform-constraint refusal; mocks not restored between tests; silent no-op when the target file is autoloaded, opcache-served, or uses a fully-qualified call; double-registration redeclare errors; parallel-run cross-contamination; false-positive green builds; CI image drift; upstream abandonment. Mitigations are process, not code: unregister() in tearDown(), a restoration assertion in every Fumocker test, opcache.enable_cli=0 in the test job, serial execution for the affected suite, and a documented fallback path.

Ramp-up. The API is small — register, unregister, scope — so the surface is learnable in an hour. The environmental and isolation knowledge is not: understanding PHP's namespace fallback for function resolution, when opcache defeats the mock, why autoload order matters, and how to debug a leaked global override. Call it one to two days of productive onboarding per engineer, gated on a short internal guide, a working CI example, and unambiguous "do not use unless…" criteria. That cost is only justified if the tool is used broadly enough to amortize it — which the overlap with Laravel's native fakes suggests it won't be. Recommendation to stakeholders: fund a two-day spike with a hard decision gate, expect the answer to be "refactor instead," and treat that as a successful outcome that retires a permanent maintenance obligation before we signed up for it.

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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager