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

Test Util Laravel Package

ergebnis/test-util

ergebnis/test-util is a lightweight collection of reusable test utilities for PHP projects, designed to reduce boilerplate and make common testing tasks clearer. Useful alongside PHPUnit for writing concise, maintainable tests with consistent helpers and assertions.

View on GitHub
Deep Wiki
Context7

Getting Started

ergebnis/test-util is a small, dev-only package from Andreas Möller's ergebnis toolchain. Its headline utility is an ObjectBuilder that lets you construct objects in tests via reflection — typically bypassing or partially satisfying the constructor — so you can cheaply produce fixtures for value objects, DTOs, and entities without writing a bespoke factory for every class.

Minimal steps:

composer require --dev ergebnis/test-util

Then look at, in order:

  1. README.md — the package is tiny and the README is effectively the full manual.
  2. src/ — a handful of classes; ObjectBuilder is the one you'll actually use.
  3. test/ — the package's own test suite demonstrates the intended API better than the docs.

A first use case is replacing repetitive fixture setup:

use function Ergebnis\Test\Util\createObjectBuilder;

$customer = createObjectBuilder(Customer::class)
    ->withId(Uuid::fromString('00000000-0000-0000-0000-000000000000'))
    ->withName('Jane Doe')
    ->build();

Because the package was last released in January 2022 and is archived, treat the pinned version and its README as the source of truth for exact method names before you build abstractions on top of it.

Implementation Patterns

Per-domain fixture helpers. Don't call the builder directly all over your suite. Wrap it once per aggregate:

final class CustomerFactory
{
    public static function create(array $overrides = []): Customer
    {
        return createObjectBuilder(Customer::class)
            ->withId($overrides['id'] ?? Uuid::uuid4())
            ->withName($overrides['name'] ?? 'Jane Doe')
            ->build();
    }
}

This gives you sensible defaults, keeps tests readable, and means the archived dependency is only referenced in one place if you later need to swap it out.

Data providers. Combine the builder with PHPUnit data providers to generate matrix cases — each provider row supplies only the attributes relevant to that scenario, and the factory fills the rest.

Named constructors and private constructors. This is where the package earns its keep: classes with private function __construct() plus static named constructors (fromString, create, etc.) are awkward to fixture. A reflection-based builder lets you construct them without threading a named constructor through every variation you want to test.

Collaborators. Built objects are ideal as collaborators passed into the class under test (a Customer into a CustomerRepository, an Order into a pricing service), while you keep real mocks/stubs only for the boundary you're actually asserting on.

Static analysis. Builder return types are usually object or static; if you run PHPStan or Psalm at a high level, add a typed wrapper (as above) or @var annotations at the call site so downstream calls are checked.

Gotchas and Tips

  • Archived status. Composer will flag the package as abandoned. Pin it ("ergebnis/test-util": "x.y.z"), keep it in require-dev only, and don't plan around future PHP/PHPUnit compatibility.
  • PHPUnit version drift. A 2022 release may have composer.json constraints that conflict with PHPUnit 10/11 or newer PHP minors. If resolution fails, copy the single builder class into your own tests/Support namespace — it's small enough that vendoring is a legitimate escape hatch.
  • Invariants are skipped. Reflection-created objects may never run constructor validation. Tests can then "pass" against states that production code cannot produce. Keep defaults valid and use overrides deliberately, not as an excuse to test impossible objects.
  • readonly properties (PHP 8.1+). Initialization semantics for readonly/typed properties via reflection differ from ordinary properties and from earlier PHP versions. Verify behavior on your target PHP before relying on it, especially for readonly promoted constructor properties.
  • Uninitialized typed properties. Any property you don't set stays uninitialized; reading it later throws Error: Typed property ... must not be accessed before initialization. That error usually points at a missing with…() call in your fixture.
  • Magic with* methods and IDEs. Dynamic setters don't autocomplete and aren't visible to static analysis. Wrapping them in your own factory (see above) fixes both discovery and type safety.
  • Autoloaded functions. If you use the namespaced createObjectBuilder() helper rather than the class directly, make sure composer dump-autoload has run — the function file is autoloaded via files, and a stale autoloader is a common "class not found" red herring in CI.
  • Final classes. The builder is likely final; extend by composition (your own factory around it), not inheritance.
  • Debugging. Reflection failures typically surface as ReflectionException naming the class or property — read the message before assuming a logic bug. When an object looks wrong, var_dump() immediately after build() rather than chasing it through the assertion.
  • Not production code. Never let this leak into src/; it exists to make test fixtures cheap, and nothing more.
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.
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
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource