Sự khác biệt giữa khẳng địnhEquals và khẳng địnhSame trong phpunit?


121

PHPUnit chứa một phương thức khẳng địnhEquals: https://phpunit.de/manual/current/en/appendes.assertions.html#appendes.assertions.assertEquals

Nó cũng có một phương thức khẳng định tên: https://phpunit.de/manual/current/en/appendes.assertions.html#appendes.assertions.assertSame

Thoạt nhìn có vẻ như họ làm điều tương tự. Sự khác biệt giữa hai là gì? Tại sao cả hai đều được chỉ định?

Câu trả lời:


198

Tôi sử dụng không thường xuyên cả hai, nhưng theo tài liệu:

assertSame

Báo cáo lỗi được xác định bởi $messagenếu hai biến $expected$actualkhông có cùng loạigiá trị . "

Và như bạn có thể thấy trong ví dụ bên dưới đoạn trích trên, chúng đang vượt qua '2204'2204sẽ không sử dụng được assertSamevì một là một stringvà một int,về cơ bản là:

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

assertEquals

"Báo cáo lỗi được xác định bởi $ message nếu hai biến $ mong đợi và $ thực tế không bằng nhau."

assertEqualsdường như không xem xét đến loại dữ liệu vì vậy sử dụng ví dụ trên về 2204:

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

Tôi vừa chạy một số bài kiểm tra đơn vị đối với các ví dụ trên và thực sự chúng dẫn đến hành vi được ghi lại.


17
khẳng địnhEquals thậm chí còn nghĩ rằng '0012' == '12'. Ngay cả khi cả hai giá trị là chuỗi, chúng được chuyển đổi thành số nguyên để so sánh! Bạn thực sự nên sử dụng ensureSame bất cứ khi nào bạn có thể.
marco-fiset

2
Thật không may, ngay cả khẳng địnhEquals dường như khá kén ví dụ khi so sánh các thuộc tính của mảng và phàn nàn về chuỗi và int sau đó.
andig

1
Theo nhận xét của marco-fiset, hãy lưu ý rằng hành vi này không còn xảy ra kể từ PHPUnit 4.0, hãy xem ghi chú nâng cấp .
Gras Double

@coviex Reference rất tuyệt, nhưng URL bị sai (vì đóng dấu ngoặc vuông) ... bạn có thể sửa nó được không? Cám ơn!
Christian

3
Lưu ý quan trọng về việc so sánh các đối tượng với assertSame(). Báo cáo lỗi được xác định bởi $ message nếu hai biến $ mong đợi và $ thực tế không tham chiếu đến cùng một đối tượng. phpunit.de/manual/current/en/…
coviex

23

Khi nói đến so sánh các đối tượng:

khẳng định: chỉ có thể khẳng định nếu 2 đối tượng đang tham chiếu đến cùng một thể hiện đối tượng. Vì vậy, ngay cả khi 2 đối tượng riêng biệt có cho tất cả các thuộc tính của chúng chính xác các giá trị giống nhau, thì khẳng định sẽ không thành công nếu chúng không tham chiếu đến cùng một trường hợp.

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

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

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

khẳng địnhEquals: có thể khẳng định nếu 2 đối tượng riêng biệt khớp với giá trị thuộc tính của chúng trong mọi trường hợp. Vì vậy, nó là phương pháp phù hợp để xác nhận đối tượng khớp.

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

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


7
Mặc dù câu trả lời này không toàn diện (nó chỉ bao gồm các đối tượng), nhưng đó chính xác là những gì tôi cần biết. Cảm ơn! :)
rinogo

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

Người đầu tiên sẽ vượt qua!

Cái thứ hai sẽ thất bại.

Đó là sự khác biệt.

Tôi nghĩ rằng bạn nên luôn sử dụng khẳng định.


Tôi vừa có gotcha này trong quá trình phát triển theo hướng thử nghiệm. đã vượt qua thử nghiệm, giả định rằng giá trị 3 đang được trả về nhưng thực tế là true đã được trả về. thú vị là $ this-> khẳng địnhEquals ('3', true); không thành công.
dwenaus

3

Như nó được nói trước, AssertSamebáo cáo một lỗi nếu hai yếu tố không chia sẻ loạigiá trị nhưng nó cũng quan trọng cần lưu ý này từ docummentation :

Báo cáo một lỗi được xác định bởi $ message nếu hai biến $ mong đợi và $ thực tế không tham chiếu đến cùng một đối tượng.

Vì vậy, thử nghiệm này cũng sẽ thất bại mặc dù chúng có chung kiểu và giá trị:

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

1

Hơn thế nữa,

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

0

khẳng địnhSame () == Kiểm tra xem đầu ra thực tế và tham số mong đợi có giống nhau không.

đó là :

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

hoặc là

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

khẳng địnhEquals == Nếu chúng ta thấy đối với một trang web, tôi có một trang có 2 "bảng", vì vậy khi tôi chạy khẳng định, tôi sẽ kiểm tra số lượng của nó rằng "bảng" là 2 bằng cách sử dụng một hàm đếm. Ví dụ:

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

Ở đây, chúng ta có thể thấy rằng khẳng định Equals kiểm tra rằng có 2 bảng được tìm thấy trên trang web. chúng tôi cũng có thể sử dụng các phân chia được tìm thấy trên trang bằng cách sử dụng '#division name' bên trong dấu ngoặc.

Vd 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
Vui lòng sử dụng định dạng mã để làm cho các phần mã dễ đọc hơn và tránh sử dụng #đánh dấu trừ khi bạn muốn tạo tiêu đề.
laalto

0

Như đã đề cập trước đây, assertEquals()chủ yếu là về một giá trị được diễn giải, có thể là theo kiểu tung hứng hoặc một đối tượng với phương thức trình bày __magic (__toString() ví dụ).

Một trường hợp sử dụng tốt assertSame()là thử nghiệm một nhà máy singleton.

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.