Twitt
@Twitt

Как сделать unit test метода в котором нужен заполненный массив?

Нужно сделать юнит тест класса, смотрю, в нем есть метод, пример:
public function checkRecords()
{
 if (empty($this->solutions)) {
       // далее что то внутри ифа
}
}

Собственно, мне нужно будет при юнит тестировании метода иметь $this->solutions в идеале не пустым, чтобы нормально потестить метод. Что делать? в setUp инициализровать какими то данными $this->solutions? как в таких ситуациях делается? при всем при том, что там в этом массиве должны находиться еще массивы. Откуда мне взять эти данные? Я в юнит тестах ранее почти не был
  • Вопрос задан
  • 509 просмотров
Решения вопроса 1
Maksclub
@Maksclub Куратор тега PHP
maksfedorov.ru
По-хорошему $this->solutions должно устанавливаться через конструктор, потому вам не составит труда заинжектить это состояние в тестируемый объект.

Если у вас "пришлось", то можете заюзать некий хак, например через рефлексию/closure::bind установить состояние в тестируемый объект.

Вот на скорую руку накидал (Разместите его в своем TestCase или прямо в тесте)
protected function setPrivateProperty(object $object, string $propertyName, $value): void
{
    $reflectionClass = new \ReflectionClass(get_class($object));
    $property = $reflectionClass->getProperty($propertyName);
    
    $property->setAccessible(true);
    $property->setValue($object, $value);
    $property->setAccessible(false);
}


ПРИМЕР
Класс и метод, который нужно протестить и приватная переменная которого заполняется не через конструктор
class System 
{
    // Не важно, как оно будет заполнено, важно, 
    // что в методе мы проверяем некоторые значения  
    // и мы создадим ниже в тестах эти ситуации разными тест-кейсами
    private $solutions;

    public function checkRecords(): string
    {
        if (count($this->solutions) === 3) {
            return 'full';
        }

        if (count($this->solutions) === 6) {
            return 'overflow';
        }

        throw new IncorrectCountException('Incorrect solutions count.');
    }
}


Тесты
public function testCheckRecordsFull(): void
    {
        // 3 элемента
        $data = [1, 2, 3];
        $system = new System();
        $this->setPrivateProperty($system, 'solutions',  $data);

        $status = $system->checkRecords();

        $this->assertEquals('full', $status);
    }

    public function testCheckRecordsOverFlow(): void
    {
        // 6 элементов
        $data = [1, 2, 3, 4, 5, 6];
        $system = new System();
        $this->setPrivateProperty($system, 'solutions',  $data);

        $status = $system->checkRecords();

        $this->assertEquals('overflow', $status);
    }

    public function testCheckRecordsIncorrectCOunt(): void
    {
        // сколько-то элементов, но не 3 и не 6
        $data = [1];
        $system = new System();
        $this->setPrivateProperty($system, 'solutions',  $data);

        $this->expectException(IncorrectCountException::class);
        $system->checkRecords();
    }

Код тестовый, просто отобразить принцип, возможно у вас в классе зависимости -- нужно будет сделать моки и т.д. Тут некоторые повторения можно вынести в setUp().
Также хочу обратить внимание, что тесты построены по принципу ААА (Arrange, Act, Assert).
Как итог, 3 ситуации, все протестированы, методу не важно, как заполнлась приватная переменная, но вся его логика протестирована. Все легко и просто.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы