Phpunit: assertType(), вызывающий автозагрузчик для скалярных типов

Созданный на 23 нояб. 2010  ·  10Комментарии  ·  Источник: sebastianbergmann/phpunit

При использовании assertType() для проверки того, является ли значение массивом или скалярным значением, вызывается автозагрузчик (как побочный эффект использования class_exists()). Было бы неплохо сначала проверить, соответствует ли строковый параметр ожидаемого типа «массиву» или скалярному типу.

Пример:

$this->assertType('массив', массив());

Ожидается: правда, без вызова автозагрузчика
Факт: правда, вызов автозагрузчика для класса с именем "массив"

Самый полезный комментарий

Пожалуйста, используйте assertInternalType() вместо assertType() для внутренних типов.

Все 10 Комментарий

Пожалуйста, используйте assertInternalType() вместо assertType() для внутренних типов.

Это работает, но зачем это нужно?

Вот код assertType:

public static function assertType($expected, $actual, $message = '')
{
    if (is_string($expected)) {
        if (PHPUnit_Util_Type::isType($expected)) {
            if (class_exists($expected) || interface_exists($expected)) {
                throw new InvalidArgumentException(
                  sprintf('"%s" is ambigious', $expected)
                );
            }

Мне кажется, что PHPUnit_Util_Type::isType уже проверяет, является ли тип внутренним типом, поэтому все, что вам нужно изменить, это следующее:

            if (class_exists($expected, false) || interface_exists($expected, false)) {

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

Я должен согласиться с arnoschaefer, почему вы требуете, чтобы мы использовали другую функцию, когда его решения достаточно? Я не буду менять тысячи уже существующих модульных тестов, использующих assertType из версии < 3.5. Поэтому я буду переопределять assertType для всех своих модульных тестов с помощью этого решения. Я думаю, что мы заслуживаем лучшего объяснения, почему вы выбрали этот путь, иначе мне придется объявить phpunit FAIL.

Один метод актива не может реализовать две разные функции. Моей ошибкой было изначально предположить, что это возможно. Вот почему сейчас существует assertInternalType() .

Пожалуйста, объясните, почему один метод утверждения не может реализовать две разные функции?

Кроме того, ваша документация противоречит этому утверждению:

http://www.phpunit.de/manual/3.5/en/api.html#api.assert.assertType :

В качестве альтернативы $expected может быть одной из этих констант для указания внутреннего типа:

* PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY ("array")
* PHPUnit_Framework_Constraint_IsType::TYPE_BOOL ("bool")
* PHPUnit_Framework_Constraint_IsType::TYPE_FLOAT ("float")
* PHPUnit_Framework_Constraint_IsType::TYPE_INT ("int")
* PHPUnit_Framework_Constraint_IsType::TYPE_NULL ("null")
* PHPUnit_Framework_Constraint_IsType::TYPE_NUMERIC ("numeric")
* PHPUnit_Framework_Constraint_IsType::TYPE_OBJECT ("object")
* PHPUnit_Framework_Constraint_IsType::TYPE_RESOURCE ("resource")
* PHPUnit_Framework_Constraint_IsType::TYPE_STRING ("string")

Ваше примечание ниже только «рекомендует» использовать assertInternalType и что это не требуется:

Примечание

Вместо проверки внутренних типов рекомендуется использовать assertInternalType (см. раздел «assertInternalType()»).

Один метод утверждения не может реализовать две разные функции, потому что они неоднозначны. Допустим, у вас есть класс с именем String и вы используете assertType("string", ...) — как PHPUnit должен знать, что вы хотите?

Рекомендация именно для вашего случая: вы используете автозагрузчик и хотите использовать assertType() . Это не работает.

В то время как php позволяет называть класс целым числом или строкой, ваш код в настоящее время не позволяет классу называться строкой, целым числом и т. д., поскольку это приведет к исключению недопустимого аргумента (%s неоднозначен).

Проблема в том, что если вы не установите для параметра автозагрузки значение false в функциях class_exists и interface_exists в строке 1208, автозагрузчик попытается включить несуществующий файл (например, class.array.php) и выдаст ошибку php. вместо исключения.

Внесение этой модификации позволит использовать assertType, как это было всегда.

Нет, не будет. Потому что тогда другие люди будут кричать на меня / PHPUnit, потому что они ожидают, что автозагрузка автоматически загрузит их класс String .

Вот мой совет, принимай или уходи:

Не используйте assertType() . Он устарел (хотя я забыл пометить его как таковой) и в конечном итоге исчезнет. Он существует только в текущих версиях PHPUnit для облегчения миграции.

Используйте assertInternalType() , чтобы утверждать, что переменная имеет указанный внутренний тип.

Используйте assertInstanceOf() , чтобы утверждать, что объект имеет указанный тип (класс или интерфейс).

У меня нет проблем с устаревшей функцией, но вы совсем не облегчаете миграцию. Вы изменили исходную функциональность phpunit 3.4, в которой изначально не было этого исключения, и теперь он ломает мой код вместо парня, который автоматически загружает класс String. Поэтому я думаю, что вы должны либо полностью удалить его в phpunit 3.5, либо вернуть его обратно к функциональности 3.4.

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги