Я разрабатываю модульные тесты для проекта и наткнулся на класс, не содержащий конструктора.
Вы можете спросить себя: «Как же тогда существует этот объект?»
Что ж, в другой системе этот объект создается и сохраняется в базе данных, поэтому в системе, где требуются модульные тесты, для этого класса не определен конструктор. Но есть необходимость протестировать их функции, чтобы, если они будут изменены в системе в будущем, тесты указали, в каких ситуациях они используются, это гарантирует, что я не пренебрегу другими точками проекта, которые его используют.
Как вы можете протестировать этот тип класса в этой среде?
Я пробовал использовать макеты, но макет возвращает все нулевые атрибуты. Кроме того, имитируемый объект появляется только в результате выполнения функции, которую, как вы сказали ранее, он будет выполнять. Таким образом, чтобы проверить функции самого объекта, это не работает.
Любая идея?
PS: Извините за плохой английский.
Да, предположим, что этот класс содержит функцию, которая что-то делает с атрибутом, класс, инициализированный, как вы упомянули, принесет мне null
Если вы хотите проверить, ведет ли функция должным образом, когда конкретный атрибут имеет определенное значение, вам все равно нужно будет установить значение этого атрибута самостоятельно, независимо от того, сделал ли с ним что-нибудь конструктор: $testObj->some_attribute = 'some_value'; $this->assertEqual('expectedResult', $testObj->functionThatDoesSomethingWithSomeAttribute());






Конструкторы необязательны. Классу не нужен конструктор, чтобы вы могли создать его экземпляр или проверить, правильно ли работают его методы.
Насколько я понимаю, вы хотите протестировать метод, который ведет себя по-разному в зависимости от конкретного свойства, которое обычно устанавливается конструктором, а в вашем классе - нет. Это означает, что при фактическом использовании кода это свойство, вероятно, устанавливается непосредственно в какой-то момент или существует другой метод, который устанавливает его значение.
В общем, для тестирования таких методов вы всегда должны устанавливать такое свойство самостоятельно. Причина этого проста: один тест должен Только проверять один конкретный метод. Если вы полагаетесь на конструктор, ваш тест будет проверять комбинация как конструктора, так и этого метода. Ваш тест метода будет зависеть от правильного поведения конструктора.
Представьте себе следующее:
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. Но здесь есть две проблемы:
$happy - это false.$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().
Большое спасибо! Это очень помогло!
Классу не нужен конструктор, чтобы вы могли его инициализировать или тестировать. Вы все еще можете выполнить
$testObj = new MyClass();, а затем проверить, ведет ли себя$testObj->someFunction()должным образом. Сталкивались ли вы с какими-либо проблемами с классом, который вы пытаетесь протестировать?