Perbedaan antara assertEquals dan assertSame di phpunit?


Jawaban:


198

Saya menggunakan keduanya secara sporadis, tetapi menurut dokumen:

assertSame

Melaporkan kesalahan yang diidentifikasi oleh $messagejika dua variabel $expecteddan $actualtidak memiliki jenis dan nilai yang sama . "

Dan seperti yang Anda lihat pada contoh di bawah kutipan di atas, mereka melewati '2204'dan 2204, yang akan gagal digunakan assertSamekarena satu adalah a stringdan satu int,pada dasarnya adalah:

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

assertEquals

"Melaporkan kesalahan yang diidentifikasi oleh $ message jika dua variabel $ yang diharapkan dan $ aktual tidak sama."

assertEqualstampaknya tidak mempertimbangkan tipe data, jadi gunakan contoh di atas 2204:

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

Saya baru saja menjalankan beberapa unit test terhadap contoh-contoh di atas, dan memang mereka menghasilkan perilaku yang terdokumentasi.


17
assertEquals bahkan berpikir demikian '0012' == '12'. Meskipun kedua nilai adalah string, keduanya akan diubah menjadi bilangan bulat untuk perbandingan! Anda harus benar-benar menggunakan assertSame kapan pun Anda bisa.
marco-fiset

2
Sayangnya bahkan assertEquals tampaknya menjadi pilih-pilih misalnya ketika membandingkan properti array dan mengeluh tentang string vs int.
andig

1
Mengikuti komentar marco-fiset, perhatikan bahwa perilaku ini tidak lagi menjadi masalah sejak PHPUnit 4.0, lihat catatan peningkatan .
Gras Double

Referensi @coviex keren, tetapi URL-nya salah (karena tanda kurung siku tutup) ... bisakah Anda memperbaikinya? Terima kasih!
Christian

3
Catatan penting tentang membandingkan objek dengan assertSame(). Melaporkan kesalahan yang diidentifikasi oleh $ message jika dua variabel $ diharapkan dan $ aktual tidak merujuk objek yang sama. phpunit.de/manual/current/en/…
coviex

23

Dalam hal perbandingan objek:

assertSame: hanya dapat menegaskan jika 2 objek mereferensikan instance objek yang sama. Jadi, meskipun 2 objek terpisah untuk semua atributnya memiliki nilai yang persis sama, assertSame akan gagal jika tidak mereferensikan instance yang sama.

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

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

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

assertEquals: dapat menegaskan jika 2 objek terpisah cocok dengan nilai atributnya dalam hal apa pun. Jadi itu metode yang cocok untuk menyatakan kecocokan objek.

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

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


7
Meskipun jawaban ini tidak komprehensif (hanya mencakup objek), itulah yang perlu saya ketahui. Terima kasih! :)
rinogo

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

Yang pertama akan lewat!

Yang kedua akan gagal.

Itulah perbedaannya.

Saya pikir Anda harus selalu menggunakan assertSame.


Saya baru saja mendapatkan gotcha ini selama pengembangan yang didorong oleh pengujian. tes lulus, mengasumsikan nilai 3 dikembalikan tetapi sebenarnya benar dikembalikan. menariknya $ this-> assertEquals ('3', true); gagal.
dwenaus

3

Seperti yang telah dikatakan sebelumnya, AssertSamemelaporkan kesalahan jika kedua elemen tidak berbagi jenis dan nilai tetapi penting juga untuk mencatat ini dari dokumentasi :

Melaporkan kesalahan yang diidentifikasi oleh $ message jika dua variabel $ diharapkan dan $ aktual tidak merujuk objek yang sama.

Jadi tes ini akan gagal juga meskipun mereka memiliki tipe dan nilai yang sama:

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

1

Bahkan,

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

0

assertSame () == Menguji apakah keluaran aktual dan parameter yang diharapkan sama.

itu adalah :

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

atau

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

assertEquals == Jika kita melihat sehubungan dengan halaman situs web, saya memiliki halaman yang memiliki 2 'tabel' jadi ketika saya menjalankan assertEquals saya akan memeriksa hitungannya bahwa 'tabel' adalah 2 dengan menggunakan fungsi hitungan. Misalnya:

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

Di sini kita dapat melihat assertEquals memeriksa bahwa ada 2 tabel yang ditemukan di halaman web. kita juga dapat menggunakan divisi yang ditemukan di halaman menggunakan '# nama divisi' di dalam tanda kurung.

Misalnya 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
Harap gunakan pemformatan kode untuk membuat bagian kode lebih terbaca, dan hindari penggunaan #markup kecuali Anda ingin membuat tajuk.
laalto

0

Seperti yang disebutkan sebelumnya, assertEquals()ini terutama tentang nilai yang ditafsirkan, baik itu dengan jenis juggling atau objek dengan metode presentasi __magic ( __toString()misalnya).

Kasus penggunaan yang baik assertSame()adalah menguji pabrik tunggal.

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.