BeBat/Verify includes almost all the assertions built into PHPUnit, and all the ones from bebat/filesystem-assertions, but there may be additional assertions you need in your project. Depending on the number and complexity of assertions you want to add, BeBat/Verify includes two ways for you to extend it and add your own assertions.

Custom Constraint

Constraints are the building blocks for both PHPUnit and BeBat/Verify’s assertions. It is possible to write your own constraints by extending PHPUnit’s Constraint class.

To assert a constraint, pass it to BeBat/Verify’s constraint() method after a conjunction, just like any other assertion. For example, if you had the package helmich/phpunit-json-assert installed:

use Helmich\JsonAssert\Constraint\JsonValueMatches;
use Helmich\JsonAssert\Constraint\JsonValueMatchesSchema;
use PHPUnit\Framework\Constraint\IsEqual;

use function BeBat\Verify\verify;

// ...

$jsonDocument = [
    'id'          => 1000,
    'username'    => 'mhelmich',
    'given_name'  => 'Martin',
    'family_name' => 'Helmich',
    'age'         => 27,
    'hobbies'     => [
        "Heavy Metal",
        "Science Fiction",
        "Open Source Software"

$schema = [
    'type'       => 'object',
    'required'   => ['username', 'age'],
    'properties' => [
        'username' => ['type' => 'string', 'minLength' => 3],
        'age'      => ['type' => 'number']

verify($jsonDocument)->has()->constraint(new JsonValueMatchesSchema($schema))
    ->and()->constraint(new JsonValueMatches('$.username', new IsEqual('mhelmich')));

Custom Verifier

If there are multiple assertions you want to create, or your assertions involve more than one step, you should create your own verifier class. A verifier extends BeBat\Verify\API\Base and includes one or more assertion methods. You can inject your verifier to BeBat/Verify by passing its class to withVerifier(). BeBat/Verify will instantiate your verifier, passing it the current subject and its name, and then allow you to call your custom assertions from it.

The withVerifier() method can also be used to switch between the value and file verifiers. For example, suppose you were testing a method that created a file and returned its path. If you wanted to write assertions about both the file contents and its name, you could do so by switching between verifiers with the withVerifier() method:

use BeBat\Verify\API\File;

// ...

verify($subject->writeFile())->will()->endWith('.log')                     // assertion about the file path
    ->and()->withVerifier(File::class)->will()->contain('My Log Message'); // assertion about the file contents

For more details about writing your own verifier, see its API documentation.