Різниця між 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 та int тоді.
andig

1
Після коментаря marco-fiset зауважте, що така поведінка більше не стосується, оскільки PHPUnit 4.0 див. Примітки до оновлення .
Подвійний Гра

@coviex Довідка класна, але URL-адреса неправильна (через закриту квадратну дужку) ... чи можете ви її виправити? Дякую!
Крістіан

3
Важлива примітка щодо порівняння об'єктів із assertSame(). Повідомляє про помилку, ідентифіковану $ message, якщо дві змінні $ очікувана та $ фактична не посилаються на один і той же об’єкт. phpunit.de/manual/current/en/…
coviex

23

Якщо мова йде про порівняння об'єктів:

assertSame: може стверджувати лише якщо два об'єкти посилаються на один і той же екземпляр об'єкта. Тож навіть якщо два окремих об’єкти мають для всіх своїх атрибутів абсолютно однакові значення, 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

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

Перший пройде!

Другий вийде з ладу.

У цьому різниця.

Я думаю, що ви завжди повинні використовувати assertSame.


У мене щойно була ця готча під час розробки тестових програм. тест пройшов, припускаючи, що значення 3 повертається, але насправді повертається істина. цікаво $ this-> assertEquals ('3', правда); не вдається.
dwenaus

3

Як було сказано раніше, AssertSameповідомлення про помилку, якщо два елементи не поділяють тип і значення, але також важливо зазначити це в документації :

Повідомляє про помилку, ідентифіковану $ 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, я перевірю його кількість, що «таблиця» є 2, використовуючи функцію підрахунку. Наприклад:

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

Тут ми можемо побачити, що assertEquals перевіряє наявність двох таблиць на веб-сторінці. ми також можемо використовувати розділи, знайдені на сторінці, використовуючи "#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()йдеться насамперед про інтерпретоване значення, будь то тип женглінгу чи об'єкт із __магічним методом викладу ( __toString()наприклад).

Гарним випадком використання assertSame()є тестування однофабрикантів.

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.