¿Diferencia entre assertEquals y assertSame en phpunit?

Respuestas:

198

Uso ambos esporádicamente, pero de acuerdo con los documentos:

assertSame

Reporta un error identificado por $messagesi las dos variables $expectedy $actualno tienen el mismo tipo y valor ".

Y como puede ver en el ejemplo debajo del extracto anterior, están pasando '2204'y 2204, que fallarán al usarlo assertSameporque uno es un stringy uno es un int,básicamente:

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

assertEquals

"Reporta un error identificado por $ message si las dos variables $ esperado y $ actual no son iguales".

assertEqualsno parece tener en cuenta el tipo de datos, por lo que se utiliza el ejemplo anterior de 2204:

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

Acabo de ejecutar algunas pruebas unitarias con los ejemplos anteriores y, de hecho, resultaron en un comportamiento documentado.

Mike Purcell
fuente
17
asertEquals incluso piensa eso '0012' == '12'. Incluso si ambos valores son cadenas, ¡se convierten en números enteros para la comparación! Realmente debería usar assertSame siempre que pueda.
marco-fiset
2
Desafortunadamente, incluso assertEquals parece ser exigente, por ejemplo, cuando se comparan las propiedades de la matriz y se queja de string vs int en ese momento.
andig
1
Siguiendo el comentario de marco-fiset, tenga en cuenta que este comportamiento ya no es el caso desde PHPUnit 4.0, consulte las notas de actualización .
Gras Double
@coviex Reference es genial, pero la URL es incorrecta (debido al cierre de corchetes) ... ¿puedes arreglarlo? ¡Gracias!
Christian
3
Nota importante sobre la comparación de objetos con assertSame(). Informa de un error identificado por $ message si las dos variables $ esperado y $ actual no hacen referencia al mismo objeto. phpunit.de/manual/current/en/…
coviex
23

Cuando se trata de comparación de objetos:

assertSame: solo se puede afirmar si 2 objetos hacen referencia a la misma instancia de objeto. Entonces, incluso si 2 objetos separados tienen exactamente los mismos valores para todos sus atributos, assertSame fallará si no hacen referencia a la misma instancia.

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

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

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

assertEquals: puede afirmar si 2 objetos separados coinciden con sus valores de atributo en cualquier caso. Entonces es el método adecuado para afirmar la coincidencia de objetos.

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

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

Grigoreas P.
fuente
7
Si bien esta respuesta no es completa (solo cubre objetos), es exactamente lo que necesitaba saber. ¡Gracias! :)
rinogo
20
$this->assertEquals(3, true);
$this->assertSame(3, true);

¡El primero pasará!

El segundo fallará.

Esa es la diferencia.

Creo que siempre deberías usar assertSame.

hombre de bronce
fuente
Acabo de tener este problema durante el desarrollo impulsado por pruebas. prueba pasada, asumió que el valor 3 estaba siendo devuelto pero en realidad se devolvió verdadero. curiosamente $ this-> assertEquals ('3', verdadero); falla.
dwenaus
3

Como se ha dicho antes, AssertSameinforma un error si los dos elementos no comparten el tipo y el valor, pero también es importante tener en cuenta esto en la documentación :

Informa de un error identificado por $ message si las dos variables $ esperado y $ actual no hacen referencia al mismo objeto.

Entonces, esta prueba también fallaría aunque compartan el tipo y el valor:

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

Además,

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

asertSame () == Comprueba si la salida real y el parámetro esperado son iguales.

es decir :

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

o

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

assertEquals == Si vemos con respecto a la página de un sitio web, tengo una página que tiene 2 'tabla', por lo que cuando ejecuto assertEquals comprobaré su recuento de que la 'tabla' es 2 utilizando una función de recuento. P.ej:

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

Aquí podemos ver que assertEquals comprueba que hay 2 tablas encontradas en la página web. también podemos usar divisiones que se encuentran en la página usando '#nombre de división' dentro del corchete.

Ej. 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
fuente
1
Utilice el formato de código para que las partes del código sean más legibles y evite el uso de #marcado a menos que desee crear un encabezado.
laalto
0

Como se mencionó anteriormente, se assertEquals()trata principalmente de un valor interpretado, ya sea por tipo de malabarismo o un objeto con un método de presentación __magic ( __toString()por ejemplo).

Un buen caso de uso para assertSame() es probar una fábrica de singleton.

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