Diferença entre assertEquals e assertSame no phpunit?

Respostas:

198

Eu uso os dois esporadicamente, mas de acordo com os documentos:

assertSame

Relata um erro identificado por $messagese as duas variáveis $expectede $actualnão tiverem o mesmo tipo e valor ".

E como você pode ver no exemplo abaixo do trecho acima, eles estão passando '2204'e 2204, que falharão em usar assertSameporque one é a stringe one é int,basicamente:

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

assertEquals

"Relata um erro identificado por $ message se as duas variáveis ​​$ esperado e $ real não forem iguais."

assertEqualsparece não levar em consideração o tipo de dados, portanto, use o exemplo acima de 2204:

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

Acabei de executar alguns testes de unidade nos exemplos acima e, de fato, eles resultaram em comportamento documentado.

Mike Purcell
fonte
17
assertEquals até pensa isso '0012' == '12'. Mesmo se os dois valores forem cadeias, eles serão convertidos em números inteiros para a comparação! Você realmente deve usar assertSame sempre que puder.
marco-Fiset
2
Infelizmente, até assertEquals parece exigente, por exemplo, ao comparar as propriedades do array e reclama sobre string vs int.
27613 andig
1
Após o comentário de marco-fiset, observe que esse comportamento não é mais o caso desde o PHPUnit 4.0, consulte as notas de atualização .
Gras Double
@coviex A referência é legal, mas o URL está errado (por causa do fechamento de colchete) ... você pode corrigi-lo? THX!
Christian
3
Nota importante sobre a comparação de objetos com assertSame(). Relata um erro identificado por $ message se as duas variáveis ​​$ esperado e $ real não fazem referência ao mesmo objeto. phpunit.de/manual/current/en/…
coviex
23

Quando se trata de comparação de objetos:

assertSame: só pode afirmar se 2 objetos estão fazendo referência à mesma instância de objeto. Portanto, mesmo se dois objetos separados tiverem para todos os seus atributos exatamente os mesmos valores, assertSame falhará se eles não fizerem referência à mesma instância.

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

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

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

assertEquals: pode afirmar se 2 objetos separados correspondem aos seus valores de atributo em qualquer caso. Portanto, é o método adequado para afirmar a correspondência de objetos.

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

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

Grigoreas P.
fonte
7
Embora essa resposta não seja abrangente (abrange apenas objetos), é exatamente o que eu precisava saber. Obrigado! :)
rinogo
20
$this->assertEquals(3, true);
$this->assertSame(3, true);

O primeiro vai passar!

O segundo falhará.

Essa é a diferença.

Eu acho que você sempre deve usar assertSame.

homem de bronze
fonte
Eu só tive esse problema durante o desenvolvimento orientado a testes. teste passado, assumiu que o valor 3 estava sendo retornado, mas na verdade verdadeiro foi retornado. curiosamente $ this-> assertEquals ('3', true); falha.
dwenaus
3

Como já foi dito antes, AssertSamerelata um erro se os dois elementos não compartilham tipo e valor, mas também é importante observar isso na documentação :

Relata um erro identificado por $ message se as duas variáveis ​​$ esperado e $ real não fazem referência ao mesmo objeto.

Portanto, esse teste também falharia, apesar de compartilharem tipo e valor:

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

Além disso,

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

assertSame () == Testa se a saída real e o parâmetro esperado são iguais.

isso é :

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

ou

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

assertEquals == Se virmos em relação a uma página de site, eu tenho uma página com 2 'tabela'; portanto, quando executo assertEquals, verificarei sua contagem de que a 'tabela' é 2 usando uma função de contagem. Por exemplo:

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

Aqui podemos ver que assertEquals verifica se há 2 tabelas encontradas na página da web. também podemos usar as divisões encontradas na página usando '#division name' dentro do colchete.

Por exemplo 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
fonte
1
Use a formatação do código para tornar as partes do código mais legíveis e evite usar a #marcação, a menos que você queira criar um cabeçalho.
precisa saber é
0

Como mencionado anteriormente, assertEquals()trata-se principalmente de um valor interpretado, seja por tipo de malabarismo ou por um objeto com um método de apresentação __magic ( __toString()por exemplo).

Um bom caso de uso assertSame()é para testar uma fábrica de singleton.

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