Phpunit: assertType() 为标量类型调用自动加载器

创建于 2010-11-23  ·  10评论  ·  资料来源: sebastianbergmann/phpunit

当使用 assertType() 检查一个值是数组还是标量值时,会调用自动加载器(作为使用 class_exists() 的副作用)。 最好先检查预期的类型字符串参数是否匹配“数组”或标量类型。

例子:

$this->assertType('array', array());

预期:true,不调用自动加载器
实际:true,为名为“array”的类调用自动加载器

最有用的评论

对于内部类型,请使用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,当他的解决方案足够时,您为什么要求我们使用不同的功能? 我不会更改已经使用 < 3.5 中的 assertType 的数千个单元测试。 因此,我将使用此解决方案为我的所有单元测试覆盖 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 是模棱两可的)异常。

问题是如果你没有在第 1208 行的 class_exists 和 interface_exists 函数中将 autoload 参数设置为 false,自动加载器将尝试包含一个不存在的文件(例如 class.array.php)并抛出一个 php 错误而不是例外。

进行此修改将允许 assertType 像往常一样使用。

不,不会的。 因为那时其他人会对我/PHPUnit 大喊大叫,因为他们希望自动加载能够自动加载他们的String类。

这是我的建议,接受还是放弃:

不要使用assertType() 。 它已被弃用(尽管我忘记将其标记为这样)并且最终会消失。 它仅存在于当前版本的 PHPUnit 中以简化迁移。

使用assertInternalType()断言变量具有指定的内部类型。

使用assertInstanceOf()断言对象具有指定的类型(类或接口)。

我对已弃用的功能没有任何问题,但您根本没有缓解迁移。 您已经更改了 phpunit 3.4 的原始功能,该功能最初没有此异常,现在破坏了我的代码,而不是自动加载 String 类的人。 因此,我认为您应该在 phpunit 3.5 中将其完全删除,或者将其恢复为 3.4 功能。

安定下来,没有必要激动。 我可以接受塞巴斯蒂安的决定,这确实是有道理的,知道背后的原因就好了。 所以我将来会使用其他两个功能。 另一方面,如果 assertType 无论如何都被弃用了,为什么不让它像以前一样工作,并清楚地记录它已被弃用,将来可能会被删除。 但这当然是 Sebastian 的决定,因为这是自由软件的方式。

此页面是否有帮助?
0 / 5 - 0 等级