当使用 assertType() 检查一个值是数组还是标量值时,会调用自动加载器(作为使用 class_exists() 的副作用)。 最好先检查预期的类型字符串参数是否匹配“数组”或标量类型。
例子:
$this->assertType('array', array());
预期:true,不调用自动加载器
实际:true,为名为“array”的类调用自动加载器
对于内部类型,请使用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 的决定,因为这是自由软件的方式。
最有用的评论
对于内部类型,请使用
assertInternalType()
而不是assertType()
。