ความแตกต่างระหว่าง AssertEquals และ AssertSame ใน phpunit


121

PHPUnit มีเมธอด assertEquals: https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertEquals

นอกจากนี้ยังมีเมธอด assertSame: https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertSame

แวบแรกดูเหมือนว่าพวกเขาจะทำสิ่งเดียวกัน อะไรคือความแตกต่างระหว่างทั้งสอง? ทำไมถึงระบุทั้งคู่

คำตอบ:


198

ฉันใช้ทั้งสองอย่างเป็นระยะ ๆ แต่ตามเอกสาร:

assertSame

รายงานข้อผิดพลาดที่ระบุโดย$messageถ้าตัวแปรทั้งสอง$expectedและ$actualไม่มีประเภทและค่าเดียวกัน "

และดังที่คุณเห็นในตัวอย่างด้านล่างข้อความที่ตัดตอนมาข้างต้นพวกเขากำลังผ่านไป'2204'และ2204ซึ่งจะล้มเหลวในการใช้assertSameเพราะหนึ่งคือ a stringและหนึ่งคือint,โดยพื้นฐาน:

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

assertEquals

"รายงานข้อผิดพลาดที่ระบุโดย $ message หากตัวแปรสองตัวที่ $ คาดไว้และ $ จริงไม่เท่ากัน"

assertEqualsดูเหมือนจะไม่คำนึงถึงประเภทข้อมูลดังนั้นโดยใช้ตัวอย่างข้างต้นของ2204:

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

ฉันเพิ่งทำการทดสอบหน่วยกับตัวอย่างข้างต้นและส่งผลให้เกิดพฤติกรรมที่เป็นเอกสาร


17
assertEquals คิดอย่างนั้น'0012' == '12'ด้วยซ้ำ แม้ว่าค่าทั้งสองจะเป็นสตริง แต่ก็จะถูกแปลงเป็นจำนวนเต็มเพื่อการเปรียบเทียบ! คุณควรใช้ assertSame ทุกครั้งที่ทำได้
marco-fiset

2
น่าเสียดายที่แม้ assertEquals ดูเหมือนจะจู้จี้จุกจิกเช่นเมื่อเปรียบเทียบคุณสมบัติอาร์เรย์และบ่นเกี่ยวกับ string vs int แล้ว
andig

1
ต่อไปนี้ความคิดเห็น marco-Fiset ของหมายเหตุลักษณะการทำงานนี้จะไม่มีกรณีตั้งแต่ PHPUnit 4.0 ให้ดูที่บันทึกการอัพเกรด
Gras Double

@coviex Reference นั้นเจ๋ง แต่ URL ผิด (เพราะปิดวงเล็บเหลี่ยม) ... คุณช่วยแก้ไขได้ไหม ขอบคุณ!
Christian

3
หมายเหตุสำคัญในการเปรียบเทียบวัตถุassertSame()ด้วย รายงานข้อผิดพลาดที่ระบุโดย $ ข้อความหากตัวแปรสองตัวที่ $ คาดหวังและ $ จริงไม่อ้างอิงอ็อบเจกต์เดียวกัน phpunit.de/manual/current/en/…
coviex

23

เมื่อพูดถึงการเปรียบเทียบวัตถุ:

assertSame: สามารถยืนยันได้ก็ต่อเมื่อวัตถุ 2 ชิ้นอ้างอิงอินสแตนซ์วัตถุเดียวกัน ดังนั้นแม้ว่า 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: สามารถยืนยันได้ว่า 2 ออบเจ็กต์ที่แยกจากกันตรงกับค่าแอ็ตทริบิวต์ในทุกกรณี ดังนั้นจึงเป็นวิธีที่เหมาะสมสำหรับการยืนยันการจับคู่วัตถุ

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

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


7
แม้ว่าคำตอบนี้จะไม่ครอบคลุม (ครอบคลุมเฉพาะวัตถุ) แต่ก็เป็นสิ่งที่ฉันต้องรู้ ขอบคุณ! :)
rinogo

ใช่ แต่assertEquals()เปรียบเทียบnullและ""และแม้กระทั่ง0ที่เท่าเทียมกัน
ดานอน

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

คนแรกจะผ่าน!

อันที่สองจะล้มเหลว

นั่นคือความแตกต่าง

ฉันคิดว่าคุณควรใช้ assertSame เสมอ


ฉันเพิ่งมี gotcha นี้ในระหว่างการพัฒนาที่ขับเคลื่อนด้วยการทดสอบ ผ่านการทดสอบสมมติว่ากำลังส่งคืนค่า 3 แต่ส่งคืนจริงจริง น่าสนใจ $ this-> assertEquals ('3', จริง); ล้มเหลว
dwenaus

3

ตามที่ได้กล่าวไว้ก่อนหน้านี้AssertSameรายงานข้อผิดพลาดหากองค์ประกอบทั้งสองไม่แบ่งประเภทและมูลค่าแต่สิ่งสำคัญคือต้องสังเกตสิ่งนี้จากเอกสารประกอบ :

รายงานข้อผิดพลาดที่ระบุโดย $ ข้อความหากตัวแปรสองตัวที่ $ คาดหวังและ $ จริงไม่อ้างอิงอ็อบเจกต์เดียวกัน

ดังนั้นการทดสอบนี้ก็จะล้มเหลวเช่นกันแม้ว่าจะแบ่งประเภทและมูลค่า:

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 ฉันจะตรวจสอบการนับว่า 'ตาราง' เป็น 2 โดยใช้ฟังก์ชันนับ เช่น:

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

ที่นี่เราจะเห็นว่า assertEquals ตรวจสอบว่ามี 2 ตารางที่พบในหน้าเว็บ นอกจากนี้เรายังสามารถใช้หน่วยงานที่พบในเพจโดยใช้ "#division 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());
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.