Differenza tra assertEquals e assertSame in phpunit?


Risposte:


198

Uso entrambi sporadicamente, ma secondo la documentazione:

assertSame

Segnala un errore identificato da $messagese le due variabili $expectede $actualnon hanno lo stesso tipo e valore . "

E come puoi vedere nell'esempio sotto l'estratto sopra, stanno passando '2204'e 2204, che fallirà usando assertSameperché uno è a stringe uno è int,fondamentalmente:

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

assertEquals

"Segnala un errore identificato da $ messaggio se le due variabili $ attesa e $ effettiva non sono uguali."

assertEqualsnon sembra prendere in considerazione il tipo di dati, quindi utilizzando l'esempio sopra di 2204:

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

Ho appena eseguito alcuni test unitari rispetto agli esempi precedenti, e in effetti hanno prodotto un comportamento documentato.


17
assertEquals lo pensa persino '0012' == '12'. Anche se entrambi i valori sono stringhe, vengono convertiti in numeri interi per il confronto! Dovresti davvero usare assertSame ogni volta che puoi.
marco-fiset

2
Sfortunatamente anche assertEquals sembra essere pignolo, ad esempio quando si confrontano le proprietà di un array e si lamenta di string vs int.
e il

1
Seguendo il commento di marco-fiset, nota che questo comportamento non è più il caso da PHPUnit 4.0, vedi le note di aggiornamento .
Gras Double

@coviex Reference è interessante, ma l'URL è sbagliato (a causa della chiusura delle parentesi quadre) ... puoi aggiustarlo? Grazie!
Christian

3
Nota importante sul confronto di oggetti con assertSame(). Segnala un errore identificato da $ messaggio se le due variabili $ previste e $ effettive non fanno riferimento allo stesso oggetto. phpunit.de/manual/current/en/…
coviex

23

Quando si tratta di confronto di oggetti:

assertSame: può affermare solo se 2 oggetti fanno riferimento alla stessa istanza di oggetto. Quindi, anche se 2 oggetti separati hanno per tutti i loro attributi esattamente gli stessi valori, assertSame fallirà se non fanno riferimento alla stessa istanza.

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

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

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

assertEquals: può affermare se 2 oggetti separati corrispondono in ogni caso ai valori degli attributi. Quindi è il metodo adatto per affermare la corrispondenza degli oggetti.

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

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


7
Anche se questa risposta non è completa (copre solo gli oggetti), è esattamente quello che avevo bisogno di sapere. Grazie! :)
rinogo

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

Il primo passerà!

Il secondo fallirà.

Questa è la differenza.

Penso che dovresti sempre usare assertSame.


Ho appena avuto questo trucco durante lo sviluppo test driven. test superato, si presume che venga restituito il valore 3 ma in realtà è stato restituito true. è interessante notare che $ this-> assertEquals ('3', true); non riesce.
dwenaus

3

Come è stato detto prima, AssertSamesegnala un errore se i due elementi non condividono tipo e valore ma è anche importante notare questo dalla documentazione :

Riporta un errore identificato da $ messaggio se le due variabili $ previste e $ effettive non fanno riferimento allo stesso oggetto.

Quindi anche questo test fallirebbe anche se condividono tipo e valore:

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

1

Inoltre,

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

0

assertSame () == Verifica che se l'output effettivo e il parametro previsto sono gli stessi.

questo è :

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

o

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

assertEquals == Se vediamo rispetto a una pagina del sito web, ho una pagina che ha 2 'table' quindi quando eseguo assertEquals controllerò il suo conteggio che le 'table' siano 2 utilizzando una funzione di conteggio. Per esempio:

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

Qui possiamo vedere che assertEquals controlla che ci siano 2 tabelle trovate nella pagina web. possiamo anche usare le divisioni trovate nella pagina usando '#division name' all'interno della parentesi.

Ad esempio 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
Utilizzare la formattazione del codice per rendere le parti di codice più leggibili ed evitare di utilizzare il #markup a meno che non si desideri creare un'intestazione.
laalto

0

Come accennato in precedenza, si assertEquals()tratta principalmente di un valore interpretato, sia esso per tipo di giocoleria o un oggetto con un metodo di presentazione __magic ( __toString()ad esempio).

Un buon caso d'uso assertSame()è testare una fabbrica singleton.

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.