nunomaduro/laravel-mojito
Laravel Mojito is a lightweight testing helper by Nuno Maduro that simplifies mocking Laravel facades. Define expectations and return values with a clean, fluent API, keeping tests fast and readable without boilerplate.
Architecture fit. Mojito is a require-dev-only testing utility, not a runtime dependency. It hooks into Laravel's view factory through a trait and a small service provider to let tests assert that a view was rendered and what data it received — without actually compiling the Blade template. This is architecturally clean: it has no production surface area, no database, no queue, no config publishing, and no service container bindings that affect the app. For a Laravel shop already on PHPUnit + Mockery, it fits the existing test architecture rather than introducing a parallel one. Fit is good but narrow: it only pays off in codebases with many controller/HTTP tests that assert on view output.
Integration feasibility. Very high. Installation is a single composer require --dev nunomaduro/laravel-mojito, then use Mojito in a test case. The API is small and ergonomic (assertViewWasRendered(), assertViewWasRenderedWith(), assertViewWasNotRendered(), and now an empty-view assertion added in v0.2.8), which lowers the cost of a spike to hours, not days. The main friction remains version alignment: the package targets the Laravel 5.8–8 / PHPUnit 8–9 era.
Release review (v0.2.8). The new release adds a single assertion (empty) via one community PR. Assessment impact: additive and low-risk, but not a change in posture.
assertViewHas closures. It does not unlock new use cases.Risk. Contained but real. Key risks:
empty assertion is subject to the same class of risk. This is the highest-severity concern because it degrades test-suite trust.Key questions.
assertViewIs / assertViewHas / View::shouldReceive(...) already cover 80%+ of the value? If so, why add a dependency?empty assertion materially change how many of our tests would adopt Mojito, or is it convenience on top of an adoption decision we'd make for other reasons?Stack fit. Best fit is a Laravel monolith or modular Laravel app using Blade, PHPUnit, and Mockery, where HTTP/feature tests currently assert rendered HTML strings. Mojito lets those tests assert on view contracts (which view, which data) instead of brittle markup, decoupling tests from template churn. It is a poor fit for API-only services, Inertia/Livewire-heavy frontends, or teams standardized on Pest-only with no PHPUnit test base.
Migration path. Adoption is incremental and reversible by design. Add the trait to a shared TestCase or to individual test classes; do not modify application code. Decommissioning is equally cheap: remove the trait and replace assertions with native Laravel equivalents (assertViewIs, assertViewHas, View::shouldReceive). There is no data migration, no config, no runtime coupling — the exit cost is near zero, which remains the strongest argument for trialing it.
Compatibility. The gating constraint is the dependency matrix, and v0.2.8 does not change it:
Sequencing.
empty assertion, and measure readability and runtime delta.Maintenance. The package remains effectively frozen. v0.2.8 is a single small PR merged after a long dormancy — welcome, but not a maintenance commitment. Treat it as vendored software we may need to own: budget periodic compatibility reviews at each Laravel/PHPUnit upgrade and name a maintainer who can patch or fork. The codebase is small enough that forking is realistic (days, not months), but that cost must be acknowledged up front rather than discovered during an upgrade crunch.
Support. Community-only, no vendor SLA, no active issue triage. Internal support model should be "one named owner + documented fallback to native assertions." Do not let it become load-bearing in a way that blocks upgrades.
Scaling. No production scaling implications — it never runs in production. Test-suite scaling is favorable: isolated view tests avoid Blade compilation and markup coupling, so suites get faster and less brittle as controller tests grow. The scaling limit is organizational: the more tests depend on it, the higher the cost of the eventual fork or migration.
Failure modes.
empty assertion. Mitigate with negative tests and periodic mutation-style spot checks.Ramp-up. Very low. One trait, a handful of assertion methods, and a mental model developers already have from Mockery. A competent Laravel engineer is productive in under an hour; team-wide documentation is a short README section. The onboarding cost is not the API — it is teaching the team when to use view isolation versus native assertions, and that discipline needs a written convention.
TPM recommendation. v0.2.8 is a safe, additive update and worth taking if we are already on the package, but it does not change the adoption calculus: it is one small assertion, not evidence of a maintained dependency, and it leaves the Laravel 9+/PHPUnit 10+ gap and the zero-dependents signal untouched. Worth a bounded spike in a legacy/pinned service with view-heavy tests; not worth adopting on a modern Laravel/PHPUnit stack without a fork commitment. Continue to treat Mojito as a tactical convenience with a named owner and a documented exit to native Laravel assertions, not as a strategic test-infrastructure investment.
How can I help you explore Laravel packages today?