-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Convenient custom comparison of objects #4467
Comments
Hi @sebastianbergmann, it looks like this is the only non-static assertion, and I couldnt find any reason obvious to me. |
Thank you for bringing this oversight to my attention. |
I'm curious if it could be implemented as a single comparator, something like Otherwise how can we to check equality of two arrays of such objects now? |
One downside here is that you lose the helpful exception message that tells you why exactly the comparison of the two objects fails. For an alternative approach, I created a StrictPHPUnitExtension that enables strict comparisons of all scalar values during |
Thanks for pointing that out, Bernhard. I'll have a look at that extension. With regards to "losing the helpful exception message", I think that's just a matter of which details the failed assertion outputs: on "false" result of the object's equals method, it might indeed make sense to show a comparison of the scalar values to ease debugging. However, I am a little concerned (and that's one of the reasons why I made that feature suggestion in the first place) that there might be situations where you have to different implementations of value objects representing the same thing, e.g. a GenericThing and a SpecificThing object, but both represent the same thing from a domain perspective, so I would expect "equals" to return true. In such a case, showing a "scalar values diff" would of course make no sense at all - but I do acknowledge that that is an edge case that should not keep anybody from using/showing a "scalar value diff" by default on failed equals comparison. |
I completely agree Stefan, in such special cases, an It seems hard to me to facilitate debugging in the What does the PHPUnit core team think about progressively moving the |
…ethod PHPUnit 9.4.0 introduced the new `Assert::assertObjectEquals()` method. This commit: * Adds two traits with the same name. One to polyfill the method when not available in PHPUnit. The other to allow for `use`-ing the trait in PHPUnit versions in which the method is already natively available. * Adds an `InvalidComparisonMethodException` exception class. _PHPUnit natively throws a range of different exceptions._ _The polyfill included in this library throws one exception type - the `InvalidComparisonMethodException` - with a range of different messages._ * Logic to the custom autoloader which will load the correct trait depending on the PHPUnit version used. * Adds tests. As the polyfill contains logic to match the PHPUnit native implementation as closely as possible, while still being PHP and PHPUnit cross-version compatible, extensive unit tests have been added to ensure the behaviour of the polyfill matches that of the original function, with the exception of the _return type verification_. As return types were not available in PHP prior to PHP 7.0, the return type verification as done in the PHPUnit native implementation, has been replaced by a verification that the _returned value_ is of the required type. This provides the same safeguard as the PHPUnit native implementation, but in a PHP cross-version compatible manner. Note: the method uses `static::` to call the PHPUnit native functionality. This allows for existing method overloads in a child class of the PHPUnit native `TestCase` to be respected. Includes: * Adding information on the new polyfill to the README. * Adding the new polyfill to the existing `TestCases` classes. * Adding a few select exceptions to the PHPCS ruleset for the fixtures used in the tests. Refs: * sebastianbergmann/phpunit#4467 * sebastianbergmann/phpunit#4707 * sebastianbergmann/phpunit@1dba8c3 * sebastianbergmann/phpunit@6099c5e
…ethod PHPUnit 9.4.0 introduced the new `Assert::assertObjectEquals()` method. This commit: * Adds two traits with the same name. One to polyfill the method when not available in PHPUnit. The other to allow for `use`-ing the trait in PHPUnit versions in which the method is already natively available. * Adds an `InvalidComparisonMethodException` exception class. _PHPUnit natively throws a range of different exceptions._ _The polyfill included in this library throws one exception type - the `InvalidComparisonMethodException` - with a range of different messages._ * Logic to the custom autoloader which will load the correct trait depending on the PHPUnit version used. * Adds tests. As the polyfill contains logic to match the PHPUnit native implementation as closely as possible, while still being PHP and PHPUnit cross-version compatible, extensive unit tests have been added to ensure the behaviour of the polyfill matches that of the original function, with the exception of the _return type verification_. As return types were not available in PHP prior to PHP 7.0, the return type verification as done in the PHPUnit native implementation, has been replaced by a verification that the _returned value_ is of the required type. This provides the same safeguard as the PHPUnit native implementation, but in a PHP cross-version compatible manner. Note: the method uses `static::` to call the PHPUnit native functionality. This allows for existing method overloads in a child class of the PHPUnit native `TestCase` to be respected. Includes: * Adding information on the new polyfill to the README. * Adding the new polyfill to the existing `TestCases` classes. * Adding a few select exceptions to the PHPCS ruleset for the fixtures used in the tests. Refs: * sebastianbergmann/phpunit#4467 * sebastianbergmann/phpunit#4707 * sebastianbergmann/phpunit@1dba8c3 * sebastianbergmann/phpunit@6099c5e
…ethod PHPUnit 9.4.0 introduced the new `Assert::assertObjectEquals()` method. This commit: * Adds two traits with the same name. One to polyfill the method when not available in PHPUnit. The other to allow for `use`-ing the trait in PHPUnit versions in which the method is already natively available. * Adds an `InvalidComparisonMethodException` exception class. _PHPUnit natively throws a range of different exceptions._ _The polyfill included in this library throws one exception type - the `InvalidComparisonMethodException` - with a range of different messages._ * Logic to the custom autoloader which will load the correct trait depending on the PHPUnit version used. * Adds tests. As the polyfill contains logic to match the PHPUnit native implementation as closely as possible, while still being PHP and PHPUnit cross-version compatible, extensive unit tests have been added to ensure the behaviour of the polyfill matches that of the original function, with the exception of the _return type verification_. As return types were not available in PHP prior to PHP 7.0, the return type verification as done in the PHPUnit native implementation, has been replaced by a verification that the _returned value_ is of the required type. This provides the same safeguard as the PHPUnit native implementation, but in a PHP cross-version compatible manner. Note: the method uses `static::` to call the PHPUnit native functionality. This allows for existing method overloads in a child class of the PHPUnit native `TestCase` to be respected. Includes: * Adding information on the new polyfill to the README. * Adding the new polyfill to the existing `TestCases` classes. * Adding a few select exceptions to the PHPCS ruleset for the fixtures used in the tests. Refs: * sebastianbergmann/phpunit#4467 * sebastianbergmann/phpunit#4707 * sebastianbergmann/phpunit@1dba8c3 * sebastianbergmann/phpunit@6099c5e
Suggested by @spriebsch:
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 and overkill at worst.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.We propose a new assertion method,
assertObjectEquals()
, that makes custom comparison of objects convenient for this common use case:$method
must exist on the$actual
object$expected
object must be compatible with this declared typebool
return typeIf any of the aforementioned assumptions is not fulfilled or if
$actual->$method($expected)
returnsfalse
then the assertion fails.An inverse of
assertObjectEquals()
does not make sense to us and will not be implemented.Example
Email.php
SomethingThatUsesEmailTest.php
The text was updated successfully, but these errors were encountered: