Download the PHP package robvanaarle/php-object-seam without Composer
On this page you can find all versions of the php package robvanaarle/php-object-seam. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download robvanaarle/php-object-seam
More information about robvanaarle/php-object-seam
Files in robvanaarle/php-object-seam
Package php-object-seam
Short Description An easy way to create object seams to break dependencies with minimal code changes in order to test legacy PHP code
License BSD-3-Clause
Informations about the package php-object-seam
PHP Object Seam
A lightweight toolkit for introducing object seams into legacy PHP code to make it testable - with minimal or no changes to the Class Under Test.
Legacy PHP code can be difficult to extend and test because dependencies are tightly coupled and often hidden behind private methods, static helpers, or heavy constructors. Although refactoring is ideal, complexity and time constraints often prevent it. To safely add new features or fix bugs, automated tests must come first - but those same dependencies make adding tests hard.
In Working Effectively with Legacy Code, Michael Feathers defines a seam as “a place to alter program behavior, without changing the code.”
This library provides an implementation of object seams, enabling you to:
- Invoke private/protected behavior
- Override methods, static methods and hooks at runtime
- Capture calls for assertions
- Instantiate objects without running their original constructors
All without or minimal modifications to the original class.
Installation
composer require --dev robvanaarle/php-object-seam:^1
Requirements
PHP >= 7.0. This package supports a wide range of PHP versions to accommodate legacy codebases.
Example
Testing TemperatureApi is difficult because the only public method makes an actual HTTP request, which is problematic because it is slow, unreliable, and may incur costs. It should be refactored if possible, but when that is not an option, we can use object seams to test it.
Without modifying the class, we can use an object seam to call the private method fahrenheitToCelsius() directly to test it:
The error handling of getCurrentTemperature() can be tested by first making a small change ('incision') to the TemperatureApi class: make getWeatherData() protected. This allows for overriding the method to return controlled data:
Features
These capabilities map directly to Feathers’ dependency-breaking techniques: 'Subclass and Make Public', 'Subclass and Override' and 'Expose Static Method'.
Introspection & Invocation
- Call protected/private methods
- Call protected static methods
- Call protected/private property get/set hooks
Behavior Overrides
- Override public/protected methods
- Override public/protected static methods
- Override public/protected property hooks
Call Capturing
- Capture calls to public/protected methods
- Capture calls to public/protected static methods
- Capture calls to public/protected property hooks
Object Construction
- Instantiate objects without executing the original constructor
- Provide a custom constructor
- Defer construction and call it later
Developer Experience
- Autocomplete support in PhpStorm using
CreatesObjectSeams - Testing-framework agnostic
Why Not Create Seams Manually?
Manually creating seams usually involves writing boilerplate subclasses or duplicated logic.
PHP Object Seam provides:
- Less code - most seam logic is generated for you
- Clearer test intent - overrides are explicit
- Faster test authoring
- Reusable, configurable seam instances that can be adapted per test case
Basic Usage in tests
Usage Guide
Call non-public method
Call protected static method
Call non-public property hook
Override public or protected method
Overridden methods are executed in the scope of the object seam class.
Override with a Closure:
Override with a result value:
Override public or protected static method
Overridden static methods are executed in the scope of the object seam class.
Override with a Closure:
Override with a result value:
Override public or protected property hook
Overridden property hooks are executed in the scope of the object seam class.
Override with a Closure:
Override with a result value:
Instantiate an object with a custom constructor
or set a custom constructor and call it later:
Call original constructor
Often there is no need for a custom constructor; in that case, the original constructor can be called.
Capture and retrieve public and protected method calls
Capturing and retrieving calls allows for asserting that a method has been called and with which arguments.
Capture and retrieve public and protected static method calls
Capturing and retrieving static calls allows for asserting that a method has been called and with which arguments.
Capture and retrieve public and protected property hook calls
Capturing and retrieving calls allows for asserting that a method has been called and with which arguments.