PHPユニットでassertEqualsとassertSameの違いは?


121

PHPUnitには、assertEqualsメソッドが含まれています。https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertEquals

また、assertSameメソッドもあります。https//phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertSame

一見、彼らは同じことをしているように見えます。2つの違いは何ですか?なぜ両方とも指定されているのですか?

回答:


198

私は両方を散発的に使用していますが、ドキュメントによれば:

assertSame

で識別されるエラー報告$messageであれば2つの変数を$expected$actual同じ持っていないタイプ値を。」

上記の抜粋の下の例でわかるように、それらは'2204'and 2204でありassertSame、1つはaでstring、もう1つはint,基本的に次のように使用できません。

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

assertEquals

「2つの変数$ expectedと$ actualが等しくない場合、$ messageで識別されるエラーを報告します。」

assertEqualsはデータ型を考慮していないようですので、上記の例を使用して2204ください:

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

上記の例に対して単体テストを実行したところ、実際に文書化された動作が発生しました。


17
assertEqualsもそれを考えてい'0012' == '12'ます。両方の値が文字列であっても、比較のために整数に変換されます!できる限り実際にassertSameを使用する必要があります。
marco-fiset 2013年

2
残念なことに、assertEqualsでさえ、たとえば配列のプロパティを比較して、文字列とintについて不平を言うとき、うるさいようです。
andig

1
marco-fisetのコメントに続き、PHPUnit 4.0以降、この動作は当てはまりません。アップグレードノートを参照してください。
Gras Double

@coviex参照はすばらしいですが、URLが間違っています(角括弧が閉じているため)...修正できますか?どうも!
クリスチャン、

3
上の重要事項のオブジェクトを比較するassertSame()。2つの変数$ expectedと$ actualが同じオブジェクトを参照していない場合、$ messageで識別されるエラーを報告します。phpunit.de/manual/current/en/...
coviex

23

オブジェクトの比較になると:

assertSame:2つのオブジェクトが同じオブジェクトインスタンスを参照している場合にのみアサートできます。したがって、2つの個別のオブジェクトがすべての属性に対してまったく同じ値を持っている場合でも、それらが同じインスタンスを参照していない場合、assertSameは失敗します。

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

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

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

assertEquals:2つの個別のオブジェクトがどのような場合でも属性値と一致するかどうかをアサートできます。したがって、オブジェクトの一致をアサートするのに適したメソッドです。

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

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


7
この答えは包括的ではありませんが(オブジェクトのみを対象としています)、それはまさに私が知る必要があったものです。ありがとう!:)
rinogo

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

最初は合格です!

2番目は失敗します。

それが違いです。

いつもassertSameを使うべきだと思います。


私はテスト駆動開発中にこの問題を抱えていました。テストに合格しました。値3が返されたと想定していますが、実際にはtrueが返されました。興味深いことに、$ this-> assertEquals( '3'、true); 失敗します。
dwenaus

3

以前に述べたAssertSameように、2つの要素がタイプ値を共有していない場合はエラーを報告しますが、ドキュメントからこれに注意することも重要です

2つの変数$ expectedと$ actualが同じオブジェクトを参照していない場合、$ messageで識別されるエラーを報告します。

したがって、タイプと値を共有していても、このテストは失敗します。

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

1

また、

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

0

assertSame()==実際の出力と予期されるパラメーターが同じかどうかをテストします。

あれは :

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

または

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

assertEquals ==ウェブサイトのページに関して見ると、「テーブル」が2つあるページがあるので、assertEqualsを実行すると、カウント関数を使用して「テーブル」が2かどうかを確認します。例えば:

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

ここでは、assertEqualsがWebページに2つのテーブルがあることを確認していることがわかります。括弧内の「#division name」を使用して、ページにある分割を使用することもできます。

例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
コードの書式設定を使用してコード部分を読みやすくし、#見出しを作成する場合を除き、マークアップの使用を避けてください。
laalto 2013

0

前述のように、これassertEquals()は主に、型ジャグリングまたは__magicプレゼンテーションメソッド(__toString()たとえば)によるオブジェクトによる解釈値に関するものです。

assertSame()シングルトンファクトリのテストが適切なユースケースです。

class CacheFactoryTest extends TestCase
{
    public function testThatCacheFactoryReturnsSingletons()
    {
        $this->assertSame(CacheFactory::create(), CacheFactory::create());
    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.