phpunit中的assertEquals和assertSame之间的区别?


Answers:


198

我偶尔使用两者,但根据文档:

assertSame

报告一个错误,该错误由$message两个变量$expected类型$actual都不相同来标识。”

正如您在上面摘录下面的示例中看到的那样,它们正在传递'2204'2204assertSame由于一个是a string而一个int,基本上是一个,它们将无法使用:

'2204' !== 2204
assertSame('2204', 2204) // this test fails

assertEquals

“如果两个变量$ expected和$ actual不相等,则报告由$ message标识的错误。”

assertEquals似乎没有考虑到数据类型,因此使用上面的示例2204

'2204' == 2204
assertEquals('2204', 2204) // this test passes

我只是对上述示例进行了一些单元测试,实际上它们导致了记录的行为。


17
assertEquals甚至认为'0012' == '12'。即使两个值都是字符串,也将它们转换为整数以进行比较!只要有可能,您就应该真正使用assertSame。
marco-fiset

2
不幸的是,例如assertEquals似乎也很挑剔,例如,在比较数组属性时,然后抱怨字符串vs整数。
andig 2013年

1
根据marco-fiset的评论,请注意,自PHPUnit 4.0起,此行为不再存在,请参阅升级说明
Gras Double

@coviex参考很酷,但是URL错误(因为用方括号括起来了)...您能解决这个问题吗?谢谢!
基督教徒

3
有关将对象进行比较的重要说明assertSame()。如果两个变量$ expected和$ actual没有引用同一对象,则报告由$ message标识的错误。phpunit.de/manual/current/en/…–
coviex

23

当涉及对象比较时:

assertSame:仅在2个对象引用同一对象实例时才可以断言。因此,即使两个单独的对象的所有属性都具有完全相同的值,但如果它们未引用相同的实例,则assertSame也会失败。

    $expected = new \stdClass();
    $expected->foo = 'foo';
    $expected->bar = 'bar';

    $actual = new \stdClass();
    $actual->foo = 'foo';
    $actual->bar = 'bar';

    $this->assertSame($expected, $actual); FAILS

assertEquals:可以断言两个单独的对象在任何情况下均与其属性值匹配。因此,这是适用于断言对象匹配的方法。

    $this->assertEquals($expected, $actual); PASSES

https://phpunit.de/manual/current/zh/appendixes.assertions.html


7
虽然这个答案并不全面(仅涵盖对象),但这正是我需要知道的。谢谢!:)
rinogo '16

20
$this->assertEquals(3, true);
$this->assertSame(3, true);

第一个会通过!

第二个将失败。

那是区别。

我认为您应该始终使用assertSame。


我只是在测试驱动开发期间遇到了这个难题。测试通过,假设返回值3,但实际上返回了true。有趣的是$ this-> assertEquals('3',true); 失败。
dwenaus

3

如前所述,AssertSame如果两个元素不共享类型,则报告错误,但是从文档中记录这一点也很重要:

如果两个变量$ expected和$ actual没有引用同一对象,则报告由$ message标识的错误。

因此,即使它们共享类型和值,该测试也将失败:

class SameTest extends TestCase
{
    public function testFailure()
    {
        $this->assertSame(new stdClass, new stdClass);
    }
}

1

此外,

// Passes
$this->assertSame("123.", "123.");
$this->assertEquals("123.", "123");
// Fails
$this->assertSame("123.", "123");

0

assertSame()==测试实际输出和预期参数是否相同。

那是 :

$this->assertSame('$expected','$expected');

要么

$this->assertSame('100','100');

assertEquals ==如果我们看到某个网站页面,则我的页面上有2个“表”,因此当我运行assertEquals时,我将使用count函数检查其计数,以确认“ table”为2。例如:

$this->assertEquals(2, $var->filter('table')->count()); 

在这里,我们可以看到assertEquals检查在网页上是否找到2个表。我们也可以使用括号内的“ #divvision name”使用页面上的分区。

例如2:

public function testAdd()
{
    $calc = new Calculator();

    $result = $calc->add(30, 12);

    // assert that our calculator added the numbers correctly!
    $this->assertEquals(42, $result);
}

1
请使用代码格式来使代码部分更易读,并避免使用#标记,除非您要创建标题。
laalto

0

如前所述,assertEquals()它主要与解释值有关,例如通过杂耍类型或带有__magic表示方法的对象(__toString()例如)。

一个很好的用例assertSame()是测试一个单例工厂。

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.