使用PHPUnit区分NULL和FALSE

15

有没有人知道如何在PHPUnit中可靠地区分FALSE和NULL?

我正在尝试区分断言中的返回值中的NULL和FALSE。

以下代码失败了:

$this->assertNotEquals(FALSE, NULL);

这些断言都通过了:

$this->assertFalse(NULL);
$this->assertNull(FALSE);

编辑:为了提供一些背景,这是为了区分错误状态(FALSE)和空结果(NULL)。为确保函数正确返回,我需要区分两者。

谢谢。

编辑...针对我正在测试的一些问题,我正在添加测试。

Class testNullFalse extends PHPUnit_Framework_TestCase{


    public function test_null_not_false (){
      $this->assertNotEquals(FALSE, NULL, "False and null are not the same");
    }

    public function test_null_is_false (){
      $this->assertFalse(NULL, "Null is clearly not FALSE");
    }

    public function test_false_is_null (){
      $this->assertNull(FALSE, "False is clearly not NULL");
    }

    public function test_false_equals_null(){
      $this->assertEquals(FALSE, NULL, "False and null are not equal");
    }

    public function test_false_sameas_null(){
      $this->assertSame(FALSE, NULL, "False and null are not the same");
    }

    public function test_false_not_sameas_null(){
      $this->assertNotSame(FALSE, NULL, "False and null are not the same");
    }
}

然后是结果。

PHPUnit 3.5.10 by Sebastian Bergmann.

FFF.F.

Time: 0 seconds, Memory: 5.50Mb

There were 4 failures:

1) testNullFalse::test_null_not_false
False and null are not the same
Failed asserting that <null> is not equal to <boolean:false>.

2) testNullFalse::test_null_is_false
Null is clearly not FALSE
Failed asserting that <null> is false.

3) testNullFalse::test_false_is_null
False is clearly not NULL
Failed asserting that <boolean:false> is null.

4) testNullFalse::test_false_sameas_null
False and null are not the same
<null> does not match expected type "boolean".

FAILURES!
Tests: 6, Assertions: 6, Failures: 4.

PHPunit(至少v3.7+,如果不是更早版本)现在具有assertSame()函数,它检查两个变量是否具有相同的类型和值。 - Alister Bulman
3个回答

22

这些断言使用==,它会执行类型强制转换。Hamcrest有identicalTo($value),它使用===,而我认为PHPUnit有assertSame($expected, $actual),它也是这样做的。

self::assertSame(false, $dao->getUser(-2));

更新:回应您的评论,“它可以为NULL或对象”:

$user = $dao->getUser(-2);
self::assertTrue($user === null || is_object($user));

使用 Hamcrest 断言可以更加表达性,特别是在出现失败的情况下:

assertThat($dao->getUser(-2), anyOf(objectValue(), nullValue()));

2
谢谢。也许你可以帮我解决一个哲学问题,与此有关...如果它们进行类型强制转换,那么assertFalse、assertTrue、assertNull等的意义是什么? - KyleWpppd
@KyleWpppd 我仍在争论它们是类型安全的,如果 $this->assertFalse(null); 没有导致测试失败,那么这是一个错误 :) - edorian
1
你说得对,问题就在于如何断言我的结果不是 false。 它可以为 NULL 或对象,但 FALSE 表示查询存在问题。 - KyleWpppd
@David Harkness - 谢谢你。我一直在想是否有风格问题,但是我想让它正常工作比让它漂亮更重要。=) - KyleWpppd
@KyleWpppd - 使用assertTrue()assertFalse()的主要问题在于失败信息毫无意义:“期望为true,但实际为false”。你可以始终传递一个描述,例如self::assertTrue('user or null', ...); - David Harkness

8

1

@David 的 assertSame (+1) 是正确的,它会为你执行 === 严格比较。


但是让我问你:

你正在使用哪个版本的phpunit?

这个断言:

$this->assertFalse(null);

应该产生错误!

示例代码:

<?php

class mepTest extends PHPUnit_Framework_TestCase {

    public function testFalseNull() {
        $this->assertFalse(null);
    }

    public function testNullFalse() {
        $this->assertNull(false);
   }
}

结果:

phpunit mepTest.php

PHPUnit 3.5.12 by Sebastian Bergmann.

FF

Time: 0 seconds, Memory: 3.00Mb

There were 2 failures:

1) mepTest::testFalseNull
Failed asserting that <null> is false.

/home/.../mepTest.php:6

2) mepTest::testNullFalse
Failed asserting that <boolean:false> is null.

/home/.../mepTest.php:10

FAILURES!
Tests: 2, Assertions: 2, Failures: 2.

我需要再过一个小时左右查看一下。我认为是3.5,但我会确认一下。 - KyleWpppd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接