PHPUnit mock - вызов родительского __get / __ set / __ isset - PullRequest
1 голос
/ 25 сентября 2019

Я пытаюсь смоделировать класс, унаследовавший магические методы, но они не реализуются, и я понятия не имею, как это исправить.Вот код:

<?php
use PHPUnit\Framework\TestCase;

class AnnoyingTestCase extends TestCase
{
    public function testNoAttributes()
    {
        $mock = $this->createMock(Child::class);
        $mock->attribute = 'value';

        $this->assertEquals($mock->attribute, null);
    }
}

class Base
{
    private $attributes = [];

    public function __set($name, $value)
    {
        $this->attributes[$name] = $value;
    }

    public function __get($name)
    {
        return $this->attributes[$name] ?? null;
    }

    public function __isset($name)
    {
        return isset($this->attributes[$name]);
    }
}

class Child extends Base
{
}

Я бы ожидал, что $mock->attribute будет иметь значение, которое я ему присвоил, но это не так, потому что __set не вызывается.

Если я попытаюсьиспользовать ->addMethods(['__get', '__set']), затем выдается исключение: Trying to set mock method "__get" with addMethods(), but it exists in class "Child". Use onlyMethods() for methods that exist in the class..И все же добавление var_dump в метод __set показывает, что он не вызывается.

Что я могу сделать, чтобы у него были эти методы?Обратите внимание, что я не собираюсь реализовывать свой собственный эквивалент этих методов, я хочу, чтобы макет имел эти оригинальные методы.

1 Ответ

0 голосов
/ 25 сентября 2019

Нашли исправление для этой конкретной проблемы, но оно может принести больше вреда, чем пользы.Работает следующий код:

$mock = $this->getMockBuilder(Child::class)
    ->enableProxyingToOriginalMethods()
    ->getMock();

Однако существует проблема, заключающаяся в том, что он проксирует ВСЕ исходные вызовы методов, и нет способа сузить методы, которые вы хотите использовать для прокси.И самые большие - потенциально неработающие вызовы конструктора - описаны здесь: PHPUnit - MockBuilder :: enableProxyingToOriginalMethods () прерывается, когда оригинальный конструктор вызывает открытый метод

...