Check::that(tdd())->with($phlunit)->isAnInstanceOf(Awesomeness::class);
Fluent assertions for phpunit.
Phlunit
will make your tests:
- fluent to write: juste type
Check::that($sut)
and let auto-completion guide you. - fluent to read: very close to plain English, making it easier for non-technical people to read test code.
- fluent to troubleshoot: every failing check throws an Exception with a clear message status to ease your TDD experience.
- less error-prone: no more confusion about the order of the "expected" and "actual" values.
composer require --dev pitchart/phlunit
Write test cases and test methods as usual, just switch to Check::that()
to write your assertions :
use Pitchart\Phlunit\Check;
$integers = [1, 2, 3, 4, 5, 42];
Check::that($integers)->contains(2, 3, 42);
$heroes = "Batman and Robin";
Check::that($heroes)
->startsWith("Batman")
->contains("Robin")
;
// Collection checks
Check::that([0, 1, 2])
->isACollectionOf('integer')
->hasElementAt(1)
->and->hasNoElementAt(12)
->hasLength(3)
->hasNotLength(12)
->contains(1, 2)
->isSubsetOf(0, 1, 2, 3, 4)
->containsNoDuplicateItem()
;
// PSR-7 ResponseInterface checks
$response = (new Response(200))
->withHeader('xxx-header', 'xxx-header-value')
->withBody(Utils::streamFor('{"name": "Batman", "city": "Gotham City"}'))
;
Check::that($response)
->asJson()
->matchesSchema(['type' => 'object', 'required' => ['name'], 'properties' => ['name' => ['type' => 'string']]]);
Phlunit
provides checks for the following types and classes :
- string, boolean, integer, float, array
- xml and json formats
- iterable
- callable
- Throwable
- ResponseInterface (PSR-7)
- DateTimeInterface
Improve readability using that()
and andThat()
methods :
Check::thatCall([$spiderman, 'saveGotham'])->with('batman', 'superman')
->throws(\LogicException::class)
->that()->isDescribedBy("Sorry, we are not in the same univers!");
Check::that($batman->getFirstname())->isEqualTo('Bruce')
->andThat($batman->getLastname())->isEqualTo('Wayne');
Write custom phpunit constraints and use them thanks to methods is()
, has()
, isNot()
or hasNot()
:
class CustomConstraint extends Constraint
{
//...
}
Check::that($sut)->is(new CustomConstraint());
class CustomClassCheck implements FluentCheck
{
//...
}
// Register your custom checks for dedicated classes in phpunit's bootstrap file
Check::registerChecksFor(Custom::class, CustomClassChecks::class);
//
Check::that(Check::that(new Custom))->isAnInstanceOf(CustomClassChecks::class);
Phlunit
provides a simple and extensible way to implement the test data builder pattern.
Here is the recommended way to use it, to not break the fluent experience:
use Pitchart\Phlunit\Builder;
class HeroBuilder extends Builder
{
protected function __construct(array $arguments)
{
parent::__construct(Hero::class, $arguments);
}
public function build(): Hero
{
return $this->buildInstance();
}
public static function create(): self
{
return new self([
'name' => 'Batman',
'firstname' => 'Bruce',
'lastname' => 'Wayne',
]);
}
public static function batman(): self
{
return self::create();
}
}
// Use it in your test cases:
$batman = HeroBuilder::batman()->build();
$superman = HeroBuilder::create()
->withName('Superman')
->andFirstname('Clark')
->andLastname('Kent')
->build()
;
Phlunit
provides a fluent way to expect exception from your code, using the Expect
class:
use Pitchart\Phlunit\Expect;
public function test_an_exception_is_thrown()
{
Expect::after($this)
->anException(\InvalidArgumentException)
->describedBy('An exception message')
->havingCode(42);
// Act
}
This package has been mainly inspired by NFluent and AssertJ
Thanks to Bruno Boucard for the inspiration.
The MIT Licence