Skip to content

Commit c8aca69

Browse files
Document assertObjectEquals()
1 parent 2edd7d0 commit c8aca69

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed

src/assertions.rst

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,6 +1014,104 @@ Please read "`What Every Computer Scientist Should Know About Floating-Point Ari
10141014
FAILURES!
10151015
Tests: 1, Assertions: 1, Failures: 1.
10161016
1017+
.. _appendixes.assertions.assertObjectEquals:
1018+
1019+
assertObjectEquals()
1020+
####################
1021+
1022+
``assertObjectEquals(object $expected, object $actual, string $method = 'equals', string $message = ''])``
1023+
1024+
Reports an error identified by ``$message`` if ``$actual`` is not equal to ``$expected`` according to ``$actual->$method($expected)``.
1025+
1026+
It is a bad practice to use ``assertEquals()`` (and its inverse, ``assertNotEquals()``) on objects without registering a custom comparator that customizes how objects are compared. Unfortunately, though, implementing custom comparators for each and every object you want to assert in your tests is inconvenient at best.
1027+
1028+
The most common use case for custom comparators are Value Objects. These objects usually have an ``equals(self $other): bool`` method (or a method just like that but with a different name) for comparing two instances of the Value Object's type. ``assertObjectEquals()`` makes custom comparison of objects convenient for this common use case:
1029+
1030+
.. code-block:: php
1031+
:caption: Usage of assertObjectEquals()
1032+
:name: appendixes.assertions.assertObjectEquals.example
1033+
1034+
<?php declare(strict_types=1);
1035+
use PHPUnit\Framework\TestCase;
1036+
1037+
final class SomethingThatUsesEmailTest extends TestCase
1038+
{
1039+
public function testSomething(): void
1040+
{
1041+
$a = new Email('[email protected]');
1042+
$b = new Email('[email protected]');
1043+
$c = new Email('[email protected]');
1044+
1045+
// This passes
1046+
$this->assertObjectEquals($a, $b);
1047+
1048+
// This fails
1049+
$this->assertObjectEquals($a, $c);
1050+
}
1051+
}
1052+
1053+
.. code-block:: php
1054+
:caption: Email value object with equals() method
1055+
:name: appendixes.assertions.Email.example
1056+
1057+
<?php declare(strict_types=1);
1058+
final class Email
1059+
{
1060+
private string $email;
1061+
1062+
public function __construct(string $email)
1063+
{
1064+
$this->ensureIsValidEmail($email);
1065+
1066+
$this->email = $email;
1067+
}
1068+
1069+
public function asString(): string
1070+
{
1071+
return $this->email;
1072+
}
1073+
1074+
public function equals(self $other): bool
1075+
{
1076+
return $this->asString() === $other->asString();
1077+
}
1078+
1079+
private function ensureIsValidEmail(string $email): void
1080+
{
1081+
// ...
1082+
}
1083+
}
1084+
1085+
.. parsed-literal::
1086+
1087+
$ phpunit EqualsTest
1088+
PHPUnit |version|.0 by Sebastian Bergmann and contributors.
1089+
1090+
F 1 / 1 (100%)
1091+
1092+
Time: 00:00.017, Memory: 4.00 MB
1093+
1094+
There was 1 failure:
1095+
1096+
1) SomethingThatUsesEmailTest::testSomething
1097+
Failed asserting that two objects are equal.
1098+
The objects are not equal according to Email::equals().
1099+
1100+
/home/sb/SomethingThatUsesEmailTest.php:16
1101+
1102+
FAILURES!
1103+
Tests: 1, Assertions: 2, Failures: 1.
1104+
1105+
Please note:
1106+
1107+
* A method with name ``$method`` must exist on the ``$actual`` object
1108+
* The method must accept exactly one argument
1109+
* The respective parameter must have a declared type
1110+
* The ``$expected`` object must be compatible with this declared type
1111+
* The method must have a declared ``bool`` return type
1112+
1113+
If any of the aforementioned assumptions is not fulfilled or if ``$actual->$method($expected)`` returns ``false`` then the assertion fails.
1114+
10171115
.. _appendixes.assertions.assertFalse:
10181116

10191117
assertFalse()

0 commit comments

Comments
 (0)