2017-06-16 118 views
2

PHPUnit中它很容易斷言,兩個數組包含相同的值:測試iterables PHPUnit中

$this->assertEquals([1, 2, 3], [1, 2, 3]); 

最新的PHP版本做迭代器和發電機很多更具吸引力的使用,以及PHP 7.1引入了the iterable pseudo-type。這意味着我可以編寫函數來獲取並返回iterable,而不會與我使用簡單的舊array或使用懶惰Generator的事實相結合。

如何聲明返回iterable函數的返回值?理想情況下我可以做類似

$this->assertIterablesEqual(['expected', 'values'], $iterable); 

有沒有這樣的功能?或者,有沒有一種合理的測試方法,不需要在我的測試中增加一堆除此之外的命令式代碼?

回答

1

你可以使用iterator_to_array功能,例如:

$expected = [1, 2, 3]; 
$this->assertEquals($expected, iterator_to_array($iterable)); 

這適用於generators也。

希望這有助於

+0

如果你有一個'Traversable'並且只關心值yes,那麼這個方法就行得通。但它不適用於'iterable',因爲'iterator_to_array'只需要'Traversable'。 –

1

我認爲你需要包裹可迭代第一。舉個例子,對於可迭代可以在迭代花園中找到一個裝飾命名ForeachIterator這是decorating anything foreach-able作爲Traversable的

$iterator = new ForeachIterator($iterable); 
$this->assertEquals([1, 2, 3], itarator_to_array($iterator)); 

注意爲細節,它也會考慮對象可迭代該測試對於正確的測試來說不夠嚴格。

但是這應該是很容易轉化爲測試私有輔助方法,只能求助於陣列和穿越的對象 - 不是非穿越的對象 - 到一個迭代器/陣列和應用斷言:

private function assertIterablesEqual(array $expected, iterable $actual, $message = '') 
{ 
    $array = is_array($actual) ?: iterator_to_array($actual); 
    $this->assertEquals($expected, $array, $message); 
} 

這可以進一步extracted into an assertion class to extend Phpunit itself

請注意,iterator_to_array將替換具有重複鍵的條目,從而產生具有重複鍵的最後一個迭代值的數組。如果您還需要斷言迭代鍵,則可能需要修飾或更改遍歷方法。