PHPUnitAssert真一(1)

vecaoik1  于 2023-01-19  发布在  PHP
关注(0)|答案(3)|浏览(98)

我正在看PHPUnit,下面的内容让我产生了疑问。PHPUnit是否将int.1和0作为布尔值处理?在我目前的测试中,它没有。
示例:$this->assertTrue(preg_match('/asdf/', 'asdf'));
在我的测试中,这是失败的,因为preg_match()返回int 1或0,如果有错误,则只返回bool false。
显然,我认为下面的代码是有效的,因为比较总是返回bool.$this->assertTrue(preg_match('/asdf/', 'asdf') === 1);
我是否在preg_match中遗漏了什么,或者我的Assert使它......不那么严格?
编辑:assertTrue要求类型匹配吗?有没有办法让Assert不那么严格?

dced5bon

dced5bon1#

PHP有单独的boolean类型,它的值TRUEFALSE(不区分大小写的常量)不等于整数值1和0。
使用严格比较(===)时,它不起作用:TRUE !== 1FALSE !== 0
当你使用类型变换时,TRUE被转换成1,FALSE被转换成0(反之亦然,0被转换成FALSE,其他任何整数都被转换成TRUE)。
在PHPUnit中,assertTrueassertFalse是依赖于类型的严格检查。assertTrue($x)检查TRUE === $x是否与assertSame(TRUE, $x)相同,而与assertEquals(TRUE, $x)不同。
在您的情况下,一种可能的方法是使用显式类型转换:

$this->assertTrue((boolean)preg_match('/asdf/', 'asdf'));

然而,PHPUnit碰巧有专门的Assert来检查字符串是否符合正则表达式:

$this->assertRegExp('/asdf/', 'asdf');
rur96b6h

rur96b6h2#

当有更具体的测试函数可用时,请不要将一堆assertTrueassertFalse检查与嵌入在复杂函数调用中的真实的逻辑一起使用。
PHPUnit有一个非常庞大的Assert集,在不满足这些Assert的情况下,它们确实很有帮助。它们为您提供了一堆出错的上下文,这有助于您进行调试。
要检查正则表达式,请使用assertRegExp()(参见http://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.assertions.assertRegExp)

dly7yett

dly7yett3#

虽然OP的例子并不是最好的,但有时候我们确实想测试一个给定的值是否可以强制为true。例如,当向MySQL中的布尔列传递一个值时,大多数ORM将接受布尔值、数字字符串或整数。
为此,可以创建自定义约束:

<?php

declare(strict_types=1);

use PHPUnit\Framework\Constraint\Constraint;

/**
 * @no-named-arguments Parameter names are not covered by the backward compatibility promise for PHPUnit
 */
final class CanBeCoercedToTrue extends Constraint
{
    /**
     * Returns a string representation of the constraint.
     */
    public function toString(): string
    {
        return 'can be coerced to true';
    }

    /**
     * Evaluates the constraint for parameter $other. Returns true if the
     * constraint is met, false otherwise.
     *
     * @param mixed $other value or object to evaluate
     */
    protected function matches(mixed $other): bool
    {
        return ((bool)$other) === true;
    }
}

您可以在如下Assert中使用它:

$this->assertThat('1', new CanBeCoercedToTrue());

您也可以在其他地方使用约束。例如:

$mockCollection->expects($this->exactly(2))
    ->method('addAttributeToFilter')
    ->with($this->equalTo('is_active'), new CanBeCoercedToTrue());

相关问题