Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between assertEquals and assertSame in PHPUnit?

Tags:

phpunit

People also ask

What is the difference between assertSame and assertEquals?

assertEquals() Asserts that two objects are equal. assertSame() Asserts that two objects refer to the same object. the assertEquals should pass and assertSame should fail, as the value of both classes are equal but they have different reference location.

What is assert in PHPUnit?

The assertEquals() function is a builtin function in PHPUnit and is used to assert whether the actual obtained value is equals to expected value or not. This assertion will return true in the case if the expected value is the same as the actual value else returns false.

How do I run PHPUnit?

How to Run Tests in PHPUnit. You can run all the tests in a directory using the PHPUnit binary installed in your vendor folder. You can also run a single test by providing the path to the test file. You use the --verbose flag to get more information on the test status.


I use both sporadically, but according to the docs:

assertSame

Reports an error identified by $message if the two variables $expected and $actual do not have the same type and value."

And as you can see in the example below the above excerpt, they are passing '2204' and 2204, which will fail using assertSame because one is a string and one is an int, basically:

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

assertEquals

"Reports an error identified by $message if the two variables $expected and $actual are not equal."

assertEquals does not appear to take datatype into consideration so using the above example of 2204:

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

I just ran some unit tests against the above examples, and indeed they resulted in documented behavior.


When it comes to objects comparison:

assertSame

Can only assert if two objects are referencing the same object instance. So even if two separate objects have for all of their attributes exactly the same values, assertSame() will fail if they don't reference the same instance.

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

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

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

assertEquals

Can assert if two separate objects match their attribute values in any case. So it's the method suitable for asserting object match.

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

Reference


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

The first one will pass!

The second one will fail.

That is the difference.

I think you should always use assertSame.


As it's been said before,AssertSame reports an error if the two elements do not share type and value but it's also important to note this from the docummentation:

Reports an error identified by $message if the two variables $expected and $actual do not reference the same object.

So this test would fail too even though they share type and value:

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

Moreover,

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