# Matchers
Verde uses matchers to validate the expected.
# Methods
- toBe(value)
- toBeCloseTo(value)
- toBeFalse()
- toBeFalsy()
- toBeFinite()
- toBeGreaterThan(value)
- toBeGreaterThanOrEqual(value)
- toBeInstanceOf(value)
- toBeLessThan(value)
- toBeLessThanOrEqual(value)
- toBeNaN()
- toBeNegativeInfinity()
- toBeNull()
- toBePositiveInfinity()
- toBeTrue()
- toBeTruthy()
- toContain(value)
- toCount(value)
- toHaveBeenCalled(value)
- toHaveBeenCalledBefore(spy)
- toHaveBeenCalledTimes(value)
- toHaveBeenCalledWith(...value)
- toHaveBeenNthCalledWith(...value)
- toHaveLength(length)
- toHaveMethod(name)
- toThrow(message)
- toThrowError(error)
# Not
Negates the assertion that follows in the chain.
<?php
use function Verde\expect;
expect(43)->not()->toBe(42);
# Reference
# toBe(value)
toBe compares the received and expected values using the === identical operator.
<?php
use function Verde\expect;
test('The Answer to Everything is 42', function() {
$answer = 42;
$everything = [
'answer' => 42,
];
expect($answer)->toBe(42);
expect($everything)->toBe(['answer' => 42]);
});
NOTE: Don't use toBe with floating-point numbers. For example, due to rounding, in PHP 0.2 + 0.1 is not strictly equal to 0.3.
If you have floating-point numbers, try toBeCloseTo instead.
# toBeCloseTo(number, ?digits)
Use toBeCloseTo to compare floating-point numbers for approximate equality.
The optional digits argument limits the number of digits to check after the decimal point. For the default value 2, the test criterion is Math.abs(expected - received) < 0.005 (that is, 10 ** -2 / 2). Intuitive equality comparisons often fail, because arithmetic on decimal (base 10) values often have rounding errors in limited precision binary (base 2) representation. For example, this test fails:
<?php
expect(0.2 + 0.1)->toBe(0.3); // Fails!
It fails because of the Floating point precision
So, toBeCloseTo solve this kind of problem by comparing the error between the expected and received number.
<?php
expect(0.2 + 0.1)->toBeCloseTo(0.3); // pass
expect(0.5 / 0.6)->toBeCloseTo(0.83, 3); // pass (we limit the check to the first 3 digits)
# toBeCountable()
Use toBeCountable to check that the received value is coutable.
This matcher uses is_coutable underneath.
<?php
use function Verde\expect;
expect([1, 2, 3]])->toBeCountable();
expect(new ArrayIterator(['foo', 'bar', 'baz']))->toBeCountable();
# toBeFalse()
Use toBeFalse to check that the received value is identical to false.
<?php
use function Verde\expect;
expect(false)->toBeFalse();
expect(0)->not()->toBeFalse();
expect("")->not()->toBeFalse();
# toBeFalsy()
Use toBeFalsy to loosely compare if received == false.
<?php
use function Verde\expect;
expect(0)->toBeFalsy();
expect("")->toBeFalsy();
expect(false)->toBeFalsy();
For more info: PHP type comparison tables
# toBeFinite()
Use toBeFinite to check whether the received value is a legal finite number or not.
<?php
use function Verde\expect;
$finite = 42;
$infinite = log(0);
$nan = acos(2);
expect($finite)->toBeFinite();
expect($infinite)->not()->toBeFinite();
expect($nan)->not()->toBeFinite();
# toBeGreaterThan(value)
Use toBeGreaterThan to compare received > expected for number values.
<?php
use function Verde\expect;
test('ounces per can is at least 10', function() {
expect(ouncesPerCan())->toBeGreaterThan(10);
});
# toBeGreaterThanOrEqual(value)
Use toBeGreaterThan to compare received >= expected for number values.
<?php
use function Verde\expect;
test('ounces per can is at least 12', function() {
expect(ouncesPerCan())->toBeGreaterThanOrEqual(12);
});
# toBeInstanceOf(class)
Use toBeInstanceOf(class) to check that the received value is an instance of class.
This matcher uses instanceof underneath.
<?php
use function Verde\expect;
class A {}
expect(new A())->toBeInstanceOf(A::class);
# toBeLessThan(value)
Use toBeLessThan to compare received < expected for number values.
<?php
use function Verde\expect;
test('ounces per can is at least 20', function() {
expect(ouncesPerCan())->toBeLessThan(20);
});
# toBeLessThanOrEqual(value)
Use toBeLessThanOrEqual to compare received <= expected for number values.
<?php
use function Verde\expect;
test('ounces per can is at least 12', function() {
expect(ouncesPerCan())->toBeLessThanOrEqual(12);
});
# toBeNaN()
Use toBeNaN to check that the received value is a NaN.
This matcher uses is_nan underneath.
<?php
use function Verde\expect;
expect(asin(2))->toBeNaN();
# toBeNegativeInfinity()
Use toBeNegativeInfinity() to check that received === -INF
<?php
use function Verde\expect;
expect(log(0))->toBeNegativeInfinity();
# toBeNull()
Use toBeNull() to check that received === null.
This matcher uses is_null underneath.
<?php
use function Verde\expect;
expect(doSomething())->toBeNull();
# toBePositiveInfinity()
Use toBePositiveInfinity() to check that received === +INF
<?php
use function Verde\expect;
expect(-log(0))->toBePositiveInfinity();
# toBeTrue()
Use toBeTrue to check that the received value is identical to true.
<?php
use function Verde\expect;
expect(true)->toBeTrue();
expect(1)->not()->toBeTrue();
# toBeTruthy()
Use toBeTruthy to loosely check if received == true.
<?php
use function Verde\expect;
expect(1)->toBeTruthy();
expect("-1")->toBeTruthy();
expect("php")->toBeTruthy();
# toContain(value)
Use toContain to check if the received string or array contains the expected value.
<?php
use function Verde\expect;
expect("hello world")->toContain("o w");
expect(['hello', 'world'])->toContain('hello');
# toCount(value)
Use toCount to compare to check that the size of received array.
<?php
use function Verde\expect;
expect(['hello', 'world'])->toCount(2);
# toHaveBeenCalled()
Use toHaveBeenCalled to ensure that the mock/spied function/method has been called.
So, let's say have a getPizzaIngredients(string $name, callable $getIngredients) function that takes a string and a callback as arguments.
We might want to make sure that the callback gets called at least once whe the name is unknown.
<?php
use function Verde\expect;
function getPizzaIngredients(string $name, callable $getIngredients) {
$pizze = [
'Margherita' => ['Mozzarella', 'Pomodoro'],
'Napolitana' => ['Origano', 'Mozzarella']
];
return $pizze[$name] ?? $getIngredients();
}
test('gets the custom ingredients when the pizza is not in the menu', function() {
$getIngredients = func();
getPizzaIngredients('Diavola', $getIngredients->getCallable());
expect($getIngredients)->toHaveBeenCalled();
});
NOTE: For more information about func have a look at mock function
# toHaveBeenCalledBefore(spy)
Use toHaveBeenCalledBefore to ensure that the mock/spiy function/method has been called before another spy.
So, let's say have a getPizzaIngredients(string $name, callable $getIngredients) function that takes a string and a callback as arguments.
We might want to make sure that the callback gets called at least once whe the name is unknown.
<?php
use function Verde\expect;
use function Verde\spyOn;
function makePizza() {
$ingredients = getPizzaIngredients();
bakePizza($ingredients);
}
test('gets the pizza ingredients before baking it', function() {
$getIngredients = spyOn('getIngredients');
$bakePizza = spyOn('bakePizza');
makePizza();
expect($bakePizza)->toHaveBeenCalledBefore($getIngredients);
});
NOTE: For more information about spyOn have a look at Spies
# toHaveBeenCalledTimes(value)
Use toHaveBeenCalledTimes to ensure that a mock function got called exact number of times.
In this example we want be sure our mock function gets called only once:
<?php
use Verde\Func;
use function Verde\expect;
function getPizzaIngredients(string $name, callable $getIngredients) {
$pizze = [
'Margherita' => ['Mozzarella', 'Pomodoro'],
'Napolitana' => ['Origano', 'Mozzarella']
];
return $pizze[$name] ?? $getIngredients();
}
test('gets the custom ingredients when the pizza is not in the menu', function() {
$getIngredients = func();
getPizzaIngredients('Diavola', $getIngredients->getCallable());
expect($getIngredients)->toHaveBeenCalledTimes(1);
});
# toHaveBeenCalledWith(...$arguments)
Use toHaveBeenCalledWith to ensure that a mock function got called, at least once, with specific arguments.
toHaveBeenCalledWith can be also used to make sure that the mock function has been called without any arguments:
<?php
use Verde\Func;
use function Verde\expect;
function getPizzaIngredients(string $name, callable $getIngredients) {
$pizze = [
'Margherita' => ['Mozzarella', 'Pomodoro'],
'Napolitana' => ['Origano', 'Mozzarella']
];
return $pizze[$name] ?? $getIngredients();
}
test('gets the custom ingredients when the pizza is not in the menu', function() {
$getIngredients = func();
getPizzaIngredients('Diavola', $getIngredients->getCallable());
expect($getIngredients)->toHaveBeenCalledWith();
});
toHaveBeenCalledWith check through all the callback invocations to see if the parameters of any them matches the expectation:
<?php
use Verde\Func;
use function Verde\expect;
function doSomething(callable $callback, $customArgs = null) {
return $callback($customArgs ?? ['hello', 'world']);
}
test('checks that the parameters of any callback invocation', function() {
$callback = func();
doSomething($callback->getCallable());
doSomething($callback->getCallable(), 'This is custom');
expect($callback)->toHaveBeenCalledWith(['hello', 'world']);
expect($callback)->toHaveBeenCalledWith('This is custom');
});
toHaveBeenCalledWith you can also check that your mock function has been called with ANY function or array using a special constant:
<?php
use Verde\ANY;
use function Verde\expect;
function doSomething(callable $callback, $customArgs = null) {
return $callback($customArgs);
}
test('checks that the mock is called with a function', function() {
$callback = func();
doSomething($callback->getCallable(), function() { return 42; });
expect($callback)->toHaveBeenCalledWith(ANY::FUNCTION);
});
test('checks that the mock is called with an array', function() {
$callback = func();
doSomething($callback->getCallable(), [1, 2, 3]);
expect($callback)->toHaveBeenCalledWith(ANY::ARRAY);
});
# toHaveBeenNthCalledWith(nthTime, ...$arguments)
If you have a mock function, you can use .toHaveBeenNthCalledWith to test what arguments it was nth called with.
<?php
$func = func();
$callable = $func->getCallable();
$callable(123);
$callable(42);
expect($func)->toHaveBeenNthCalledWith(1, 123);
expect($func)->toHaveBeenNthCalledWith(2, 42);
# toHaveLength(length)
Use toHaveLength to check that the size of an array, or the length of a string, is a certain numeric value.
<?php
expect("Ciao")->toHaveLength(4);
expect([1,2, 3])->toHaveLength(3);
expect("")->not()->toHaveLength(42);
# toHaveMethod(name)
Use toHaveMethod to check that the class method exists.
This matcher uses method_exists underneath.
<?php
expect(Dummy::class)->toHaveMethod('doSomething');
# toThrow(?message)
Use toThrow to test that a function throws when it is called.
For example, if we want to test that getPizzaIngredients throws an error when the pizza is unknown.
<?php
function getPizzaIngredients(string $name) {
$pizze = [
'Margherita' => ['Mozzarella', 'Pomodoro'],
'Napolitana' => ['Origano', 'Mozzarella']
];
return $pizze[$name] ?? throw new Error("Ingredients not found")
}
it("throws the error when we don't know the ingredients for the pizza requested", function() {
expect(function() {
return getPizzaIngredients('Diavola');
})->toThrow();
/**
* You can provide an optional argument to test that a specific error message is thrown:
*/
expect(function() {
return getPizzaIngredients('Diavola');
})->toThrow("Ingredients not found");
})
NOTE: This method checks only the error message. If you want to check the type of Error thrown, use toThrowError.
# toThrowError(errorClass, ?message)
Use toThrowError to test that a function throws a specific error class when it is called.
The difference with the toThrow is this method does also check that the error class thrown matches the expectation.
For example, if we want to test that getPizzaIngredients throws an error when the pizza is unknown.
<?php
function getPizzaIngredients(string $name) {
$pizze = [
'Margherita' => ['Mozzarella', 'Pomodoro'],
'Napolitana' => ['Origano', 'Mozzarella']
];
return $pizze[$name] ?? throw new PizzaUnknown(name + " not found")
}
it("throws the IngredientsNotFound error when we don't know the ingredients for the pizza requested", function() {
expect(function() {
return getPizzaIngredients('Diavola');
})->toThrowError(PizzaUnknown::class);
/**
* You can provide an optional argument to test that a specific error message is thrown:
*/
expect(function() {
return getPizzaIngredients('Diavola');
})->toThrowError(PizzaUnknown::class, "Diavola not found");
})
← Mock/Spy