phpunit-testingtestingmockingmockery

Does Mockery clone __get method?


I am using Laravel 9 together with mockery/mockery version 1.6.6

I have some strange behavior when I mock an Eloquent model.

The eloquent Model has a __get() method defined as :

    public function __get($key)
    {
        return $this->getAttribute($key);
    }

In my understanding, the mockery should not be aware of it.

However, the following test fails:

$user = Mockery::mock(User::class);
$user->abasdasd

with:

Mockery\Exception\BadMethodCallException : Received Mockery_1_App_User::getAttribute(), but no expectations were specified /var/www/html/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2222 /var/www/html/tests/Unit/Services/Bill/TextGenerator/RegistrationInvoiceTextTest.php:29

IT seems that "getAttribute" is called on my mock object when I try to access a property. Why is that? Is the __get() method actually inherited from the class that should be mocked?


Solution

  • It's not well-documented but it seems, like accessing magic properties proxies calls to the real magic methods by design:

    It is strongly recommended that unit tests and mock objects do not directly refer to magic methods. Instead, refer only to the virtual methods and properties these magic methods simulate. [...] Following this piece of advice will ensure we are testing the real API of classes.