Правильный способ проверить, имеет ли класс константу, определенную с помощью PHPUnit

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

У меня следующий класс:

PurchaseManager.php

/**
 * Message sent when a course has been purchased
 */
const COURSE_PURCHASED_MESSAGE = 'coursePurchasedMessage';

... и часть этого тестового класса имеет этот тест:

PurchaseManagerTest.php

public function testCoursePurchasedMessageConstant()
{
    $pm = new PurchaseManager();
    $this->assertTrue(defined(get_class($pm) . '::COURSE_PURCHASED_MESSAGE'));
}

Это верно? Он проходит, но мне просто интересно узнать, является ли это правильным и лучшим методом.

Я использую PHPUnit 5.0.8.


person crmpicco    schedule 02.09.2016    source источник


Ответы (2)


Для этого я использую класс Reflection. Он имеет getConstants метод, который возвращает ассоциативный массив [<constant_name> => <constant_value>, ...].

Что-то вроде:

public function testHasSiteExportedConstant()
{
    $mailer = new \ReflectionClass(SiteExporter::class);
    $this->assertArrayHasKey('SITE_EXPORTED', $mailer->getConstants());
}
person BVengerov    schedule 02.09.2016
comment
Спасибо. В чем преимущество использования Reflection перед моим подходом? - person crmpicco; 02.09.2016
comment
Для простых случаев подходят оба подхода, но для более сложных тестов методы отражения проще в использовании, чтении и обслуживании просто потому, что они не требуют дополнительных манипуляций (например, defined, get_class, конкатенация, ::). - person BVengerov; 02.09.2016
comment
немного лучше, потому что более прямым путем было бы $this->assertTrue($mailer->hasConstant('SITE_EXPORTED'). - person Adrian Föder; 20.06.2018

Я бы никогда не стал проверять наличие константы, атрибута или метода. Если, конечно, вы не тестируете генератор кода.

person Sebastian Bergmann    schedule 02.09.2016
comment
Спасибо за комментарий, что-то внутри меня говорило мне, что я не должен этого делать по какой-то причине, и я не уверен, почему. Я написал тесты с другими инструментами, такими как PhpSpec, и затем проверил наличие классов. Константа является важной частью моего класса, и если она отсутствует / изменена, я хотел бы знать об этом, однако вы говорите, что это неправильное использование PHPUnit? - person crmpicco; 02.09.2016
comment
Вы можете объяснить почему? - person MonkeyMonkey; 25.03.2017
comment
Если вы используете модульные тесты для формирования псевдоконтракта с тем, что ваш код публично отображается для другого кода, и этот другой код использует эту константу, и она изменяется, хорошо, что модульный тест перехватывает ее, так что вы знаете свой "контракт" также изменился. Возможно, юнит-тесты - неподходящее место для этого. ¯\_(ツ)_/¯ - person gingerCodeNinja; 13.09.2017
comment
Я бы сказал, что почти ни один сложный проект не обходится без некоторых случайных (и, надеюсь, временных) хаков, предназначенных для устранения недостатков дизайна. И такие взломы требуют лучшего тестового покрытия именно потому, что они необычны и неочевидны. Например. зависит от наличия некоторой константы :-) - person BVengerov; 12.10.2017
comment
Я согласен с Себастьяном в том, что вы не должны тестировать внутреннюю работу вещей, а только интерфейсы, то есть поведение вывода, заданное на конкретном входе. Однако я пришел сюда, чтобы проверить наличие публичной константы (что, я знаю, плохо, но так оно и есть); и поскольку он общедоступен, это каким-то образом значительный интерфейс, и поэтому я его тестирую. - person Adrian Föder; 20.06.2018