Unterschied zwischen assertEquals und assertSame in phpunit?

121

PHPUnit enthält eine assertEquals-Methode: https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertEquals

Es gibt auch eine assertSame-Methode: https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertSame

Auf den ersten Blick sieht es so aus, als würden sie dasselbe tun. Was ist der Unterschied zwischen den beiden? Warum sind beide angegeben?

Kevin Burke
quelle

Antworten:

198

Ich benutze beide sporadisch, aber laut den Dokumenten:

assertSame

Meldet einen durch identifizierten Fehler , $messagewenn die beiden Variablen $expectedund $actualnicht die gleiche haben Art und Wert .“

Und wie Sie im Beispiel unten im obigen Auszug sehen können, vergehen sie '2204'und 2204, was bei der Verwendung fehlschlägt, assertSameweil man ein stringund einer im int,Grunde ist:

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

assertEquals

"Meldet einen durch $ message identifizierten Fehler, wenn die beiden Variablen $ expected und $ actual nicht gleich sind."

assertEqualsscheint den Datentyp nicht zu berücksichtigen, also anhand des obigen Beispiels von 2204:

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

Ich habe gerade einige Unit-Tests mit den obigen Beispielen durchgeführt, und tatsächlich haben sie zu dokumentiertem Verhalten geführt.

Mike Purcell
quelle
17
assertEquals denkt das sogar '0012' == '12'. Auch wenn beide Werte Zeichenfolgen sind, werden sie für den Vergleich in Ganzzahlen konvertiert! Sie sollten assertSame wirklich verwenden, wann immer Sie können.
Marco-Fiset
2
Leider scheint sogar assertEquals wählerisch zu sein, z. B. beim Vergleichen von Array-Eigenschaften, und beschwert sich dann über string vs int.
Andig
1
Beachten Sie nach dem Kommentar von marco-fiset, dass dieses Verhalten seit PHPUnit 4.0 nicht mehr der Fall ist. Weitere Informationen finden Sie in den Upgrade-Hinweisen .
Gras Double
@coviex Referenz ist cool, aber die URL ist falsch (wegen der schließenden eckigen Klammer) ... können Sie das bitte beheben? Vielen Dank!
Christian
3
Wichtiger Hinweis zum Vergleichen von Objekten mit assertSame(). Meldet einen durch $ message identifizierten Fehler, wenn die beiden Variablen $ expected und $ actual nicht auf dasselbe Objekt verweisen. phpunit.de/manual/current/en/…
coviex
23

Wenn es um den Objektvergleich geht:

assertSame: Kann nur behaupten, wenn 2 Objekte auf dieselbe Objektinstanz verweisen. Selbst wenn zwei separate Objekte für alle Attribute genau dieselben Werte haben, schlägt assertSame fehl, wenn sie nicht auf dieselbe Instanz verweisen.

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

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

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

assertEquals: Kann bestätigen, ob 2 separate Objekte in jedem Fall mit ihren Attributwerten übereinstimmen. Es ist also die Methode, mit der die Objektübereinstimmung bestätigt werden kann.

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

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

Grigoreas P.
quelle
7
Diese Antwort ist zwar nicht vollständig (sie deckt nur Objekte ab), aber genau das musste ich wissen. Vielen Dank! :)
Rinogo
20
$this->assertEquals(3, true);
$this->assertSame(3, true);

Der erste wird vergehen!

Der zweite wird fehlschlagen.

Das ist der Unterschied.

Ich denke, Sie sollten immer assertSame verwenden.

Bronzemann
quelle
Ich hatte gerade dieses Problem während der testgetriebenen Entwicklung. Test bestanden, angenommen, dass der Wert 3 zurückgegeben wurde, aber tatsächlich wahr zurückgegeben wurde. interessanterweise $ this-> assertEquals ('3', true); schlägt fehl.
dwenaus
3

Wie bereits erwähnt, AssertSamewird ein Fehler gemeldet, wenn die beiden Elemente Typ und Wert nicht gemeinsam haben. Beachten Sie dies jedoch auch in der Dokumentation :

Meldet einen durch $ message identifizierten Fehler, wenn die beiden Variablen $ expected und $ actual nicht auf dasselbe Objekt verweisen.

Dieser Test würde also auch fehlschlagen, obwohl sie Typ und Wert gemeinsam haben:

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

Außerdem,

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

assertSame () == Testet, ob die tatsächliche Ausgabe und der erwartete Parameter identisch sind.

das ist :

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

oder

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

assertEquals == Wenn wir in Bezug auf eine Website-Seite sehen, habe ich eine Seite, die 2 'Tabelle' hat. Wenn ich assertEquals ausführe, überprüfe ich die Anzahl, dass die 'Tabelle' 2 sind, mithilfe einer Zählfunktion. Z.B:

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

Hier können wir sehen, dass assertEquals überprüft, ob 2 Tabellen auf der Webseite gefunden wurden. Wir können auch Unterteilungen verwenden, die auf der Seite mit '#division name' in der Klammer gefunden werden.

ZB 2:

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

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

    // assert that our calculator added the numbers correctly!
    $this->assertEquals(42, $result);
}
Arpan Buch
quelle
1
Verwenden Sie die Code-Formatierung, um die Codeteile besser lesbar zu machen, und vermeiden Sie die Verwendung von #Markups, es sei denn, Sie möchten eine Überschrift erstellen .
Laalto
0

Wie bereits erwähnt, assertEquals()handelt es sich in erster Linie um einen interpretierten Wert, sei es durch Typ-Jonglieren oder um ein Objekt mit einer __magischen Präsentationsmethode ( __toString()zum Beispiel).

Ein guter Anwendungsfall für assertSame()das Testen einer Singleton-Factory.

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
Richard A Quadling
quelle