2017-01-01 7 views
0

私はPHPUnitのテストを実行すると、以下のように現在のテストクラスの動作を確認したい、このケースを持っている:PHPUnitでの現在のテストクラスの予言を行うには?

public function it_allows_to_add_items() 
{ 
     // Create prophesies 
     $managerProphecy = $this->getProphet(ListingManager::class); 
     $listingItemProphecy = $this->getProphet(ListingItemInterface::class); 

     $listing = factory(\App\Misc\Listings\Listing::class)->create(); 
     $manager = new ListingManager($listing); 

     $item = factory(\App\Misc\Listings\ListingItem::class)->make(['listing_id' => null]); 
     $item2 = factory(\App\Misc\Listings\ListingItem::class)->make(['listing_id' => null]); 

     $manager->addItem($item); 
     $managerProphecy->validate($listingItemProphecy)->shouldBeCalledTimes(2); 
     $manager->addItem($item2); 

     $this->assertTrue(true); 
    } 

でも可能ということでしょうか?もちろん

私は、このテストにアプローチするあなたの方法は少しオフになっていると思います

1) GenericListingManagerTest::it_allows_to_add_items 
Some predictions failed: 
    Double\App\Misc\Listings\ListingManager\P2: 
    Expected exactly 2 calls that match: 
     Double\App\Misc\Listings\ListingManager\P2->validate(exact(Double\ListingItemInterface\P1:00000000058d2b7a00007feda4ff3b5f Object (
     'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*) 
    ))) 
    but none were made. 
+0

私はこれが可能であると思っています。これは、リストマネージャの依存関係に予言として提供されるValidatorのようなかなりよくない設計要素の代わりにです。 –

答えて

1

を取得しています。私が正しく理解していれば、addItem(object $item)が正常に動作していることを確認してください。つまり、マネージャにアイテムが含まれていて、追加したアイテムが同じです。このためには、預言は必要ないはずです。実際にあなたの試練は、あなたが作成した預言を実際には使用しません。 - あなたはカウントが追加された項目の数だけ増加するかどうかの前と後にチェックすることができる方法

function test_manager_add_items_stores_item_and_increases_count() 
{ 
    $manager = new ListingManager(); // (2) 
    $item = new ListingIem(); // (3) 
    $initialCount = $manager->countItems(); // (1) 

    $manager->addItem($item); 

    $this->assertEquals($initialCount + 1, $manager->countItems()); 
    // Assuming offset equals (item count - 1) just like in a numeric array 
    $this->assertSame($item, $manager->getItemAtOffset($initialCount)); 
} 

(1)上司と仮定すると、カウントを()があります:あなたのマネージャーは、あなたがこのような何かを書くことができますどのように見えるかに応じて、 。

(2)実際のマネージャーをテストしたいので、ここでは予言によって作成されたモックは必要ありません。単なる値なので、実際のアイテムを使うことができます。

(3)なぜあなたがListItemInterfaceを持っているのかわかりません。本当に異なるリストアの実装があるかどうか、そうであればそれらのすべてを含んでいる可能性のある一般的なリストマネージャが本当に必要なのか、それとももっと具体的なものが必要ですか?これは本当にあなたのユースケースに依存しますが、SOLIDのI(Interface Segregation Principle)やL(Liskov Substitution Principle)に違反する可能性があります。

ユースケースによっては、実際のアイテムを追加することができます。 2つの異なる型があることを明確にするために、そこにインターフェースの2つの異なる実装を置くことができることを意図しているか、または上記のようにして、単にListItemを追加してマネージャーの各項目がインターフェースを実装していることを確認する - あなたのためにそれ;)。もちろん、工場を使ってアイテムを作成することもできます。重要なのは、assertSame()でテストしたところ、管理対象オブジェクトと最初に作成したオブジェクトが同じかどうか、すなわち全く同じオブジェクトを参照するかどうかということです。

マネージャに追加できる項目の種類や無効なオブジェクトを配置したときの動作など、追加の動作を確保したい場合は、テストを追加できます。

重要なことは、Managerの実際の動作をテストすることです。そのため、モックを使用したくないということです。本当に必要な場合は、ListItemInterfaceのモックを使うことができます。

function test_manager_add_items_stores_item_and_increases_count() 
{ 
    $manager = new ListingManager(); 
    $dummyItem = $this->prophecy(ListingIemInterface::class); 
    $initialCount = $manager->countItems(); 

    $manager->addItem($dummyItem->reveal()); 

    $this->assertEquals($initialCount + 1, $manager->countItems()); 
    $this->assertSame($dummyItem, $manager->getItemAtOffset($initialCount)); 
} 

編集:あなたは、例えば、スキップしたいaddItemチェック検証もしその場合、テストは、おそらく次のようになりますあなたが提供する空のアイテムは有効ではなく、あなたは気にしないからです。あなたは部分的にこのようにマネージャーを模擬するためにPHPUnitの自身のモックフレームワークを使用することができます。

$item = new ListingItem(); 
$managerMock = $this->getMockBuilder(ListManager::class) 
    ->setMethods(['validate']) 
    ->getMock(); 
$managerMock 
    ->expects($this->exactly(2)) 
    ->method('validate') 
    ->with($this-> identicalTo($item)) 
    ->willReturn(true); 

$managerMock->addItem($item); 
$managerMock->addItem($item); 

あなたはexpects()はすでに何かを主張しているので、最後に何かを主張する必要はありません。あなたのマネージャはvalidate()を除いて正常に動作します。つまり、addItem()でコードを実行し、validateが呼び出された場合(項目ごとに1回)にテストが合格します。

+0

Actual DB接続を使用しているため、ListItemInterfaceのモック付きのこのケースは動作しません(私が書いている統合テストではありませんか?)ので、ダミーは予期したデータを提供しません。 私が追加したい別の動作テストが検証($ item)チェックであるので、私が望んだように模擬を使用することが可能かどうか疑問に思っていました。だから、PHPUnitを使用して、私はそのメソッドが実行されたかどうか(または例外がスローされたかどうかなど)を確認するためにListManagerを嘲笑することに苦労していた。 –

+0

とにかく、私はさらに一歩進んでhttps://kahlan.github.io/メソッドがトリガされたかどうかを確認できるフレームワークをテストします。 –

+0

私はあなたがテストしたいものを少し混乱させています。これはおそらく、あなたのテストが複雑すぎるか、命名がオフであるという兆候でしょう。おそらく 'addItem()'のソースコードを提供できますか?おそらく、テストしようとしているコードのサンプルが理解しやすいでしょう。 'addItem()'で呼び出されているので、両方の項目が妥当性チェックに合格していることを確認したいのであれば、Prophecyでは不可能な部分モックを調べたいかもしれません。私はそれのための例を含めるために私の答えを更新します。 – dbrumann

関連する問題