PHPUnit, тестирующий класс без конструктора

Я разрабатываю модульные тесты для проекта и наткнулся на класс, не содержащий конструктора.

Вы можете спросить себя: «Как же тогда существует этот объект?»

Что ж, в другой системе этот объект создается и сохраняется в базе данных, поэтому в системе, где требуются модульные тесты, для этого класса не определен конструктор. Но есть необходимость протестировать их функции, чтобы, если они будут изменены в системе в будущем, тесты указали, в каких ситуациях они используются, это гарантирует, что я не пренебрегу другими точками проекта, которые его используют.

Как вы можете протестировать этот тип класса в этой среде?

Я пробовал использовать макеты, но макет возвращает все нулевые атрибуты. Кроме того, имитируемый объект появляется только в результате выполнения функции, которую, как вы сказали ранее, он будет выполнять. Таким образом, чтобы проверить функции самого объекта, это не работает.

Любая идея?

PS: Извините за плохой английский.

Классу не нужен конструктор, чтобы вы могли его инициализировать или тестировать. Вы все еще можете выполнить $testObj = new MyClass();, а затем проверить, ведет ли себя $testObj->someFunction() должным образом. Сталкивались ли вы с какими-либо проблемами с классом, который вы пытаетесь протестировать?

rickdenhaan 20.04.2018 22:15

Да, предположим, что этот класс содержит функцию, которая что-то делает с атрибутом, класс, инициализированный, как вы упомянули, принесет мне null

David Alves 20.04.2018 22:18

Если вы хотите проверить, ведет ли функция должным образом, когда конкретный атрибут имеет определенное значение, вам все равно нужно будет установить значение этого атрибута самостоятельно, независимо от того, сделал ли с ним что-нибудь конструктор: $testObj->some_attribute = 'some_value'; $this->assertEqual('expectedResult', $testObj->functionThatDoesSomethingWithSomeAttribute());

rickdenhaan 20.04.2018 22:21
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
90
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Конструкторы необязательны. Классу не нужен конструктор, чтобы вы могли создать его экземпляр или проверить, правильно ли работают его методы.

Насколько я понимаю, вы хотите протестировать метод, который ведет себя по-разному в зависимости от конкретного свойства, которое обычно устанавливается конструктором, а в вашем классе - нет. Это означает, что при фактическом использовании кода это свойство, вероятно, устанавливается непосредственно в какой-то момент или существует другой метод, который устанавливает его значение.

В общем, для тестирования таких методов вы всегда должны устанавливать такое свойство самостоятельно. Причина этого проста: один тест должен Только проверять один конкретный метод. Если вы полагаетесь на конструктор, ваш тест будет проверять комбинация как конструктора, так и этого метода. Ваш тест метода будет зависеть от правильного поведения конструктора.

Представьте себе следующее:

class Mood {
    public $happy;

    function __construct() {
        $this->happy = true;
    }

    public function greet() {
        if ($this->happy) {
            return 'Hi!';
        } else {
            return 'Go away';
        }
    }
}

Допустим, вы хотите протестировать поведение метода greet():

class MoodTest extends \PHPUnit\Framework\TestCase {
    public function testGreet() {
        $mood = new Mood();
        $this->assertEqual('Hi!', $mood->greet())
    }
}

Этот тест пройдет успешно, потому что мы предполагать конструктор выполняет свою работу и устанавливает для свойства $happy значение true. Но здесь есть две проблемы:

  1. Мы не проверяем правильность работы метода, если $happy - это false.
  2. Мы полагаемся на конструктор для установки начального значения $happy на true.

Это означает, что что-то может измениться вне нашего контроля, что нарушит этот конкретный тест, даже если функция по-прежнему работает должным образом. Бизнес-логика может измениться, так что конструктор изначально установит $happy на false. Или логика разработчика может измениться, когда конструктор полностью исчезнет, ​​а $happy будет установлен другим способом (возможно, в какой-то момент будет введен метод setHappy()).

Чтобы правильно протестировать метод greet(), должен быть тест для всех возможных результатов. В этом случае метод имеет один оператор if, поэтому должен быть тестовый пример для обоих результатов этого условия:

class MoodTest extends \PHPUnit\Framework\TestCase {
    public function testGreetIfHappy() {
        $mood = new Mood();
        $mood->happy = true;
        $this->assertEqual('Hi!', $mood->greet())
    }

    public function testGreetIfNotHappy() {
        $mood = new Mood();
        $mood->happy = false;
        $this->assertEqual('Go away', $mood->greet())
    }
}

Теперь, независимо от того, что происходит с конструктором или бизнес-логикой, эти тесты проверяют Только поведение метода greet(). Что бы еще ни делал конструктор (даже если он не существует или вообще ничего не делает), больше не влияет на тесты метода greet().

Большое спасибо! Это очень помогло!

David Alves 21.04.2018 01:53

Другие вопросы по теме