2017-07-03 99 views
1

A PHPUnit data provider allows the return of an iterator,但是當使用AppendIterator時,僅使用最後附加的迭代器。我是否設置錯誤或AppendIterators不能用作PHPUnit數據提供者?phpunit和AppendIterator數據提供者?

測試文件:

<?php 

use PHPUnit\Framework\TestCase; 

class AppendIteratorTest extends TestCase 
{ 
    /** 
    * @dataProvider getAppendIterator 
    */ 
    public function testAppendIterator($item) { 
     echo PHP_EOL."test> $item".PHP_EOL; 
    } 

    public function getAppendIterator() { 
     $iterator = new AppendIterator(); 
     $iterator->append(new ArrayIterator([[0], [1]])); 
     $iterator->append(new ArrayIterator([[2], [3]])); 
     $iterator->append(new ArrayIterator([[4], [5]])); 

     foreach($iterator as $i) { 
      echo 'foreach> '.print_r($i, true); 
     } 

     return $iterator; 
    } 
} 

測試文件輸出:

$ vendor/bin/phpunit --debug AppendIteratorTest.php 
     foreach> Array 
    (
     [0] => 0 
    ) 
    foreach> Array 
    (
     [0] => 1 
    ) 
    foreach> Array 
    (
     [0] => 2 
    ) 
    foreach> Array 
    (
     [0] => 3 
    ) 
    foreach> Array 
    (
     [0] => 4 
    ) 
    foreach> Array 
    (
     [0] => 5 
    ) 
    PHPUnit 6.2.3 by Sebastian Bergmann and contributors. 


    Starting test 'AppendIteratorTest::testAppendIterator with data set #0 (4)'. 
    R 
    test> 4 

    Starting test 'AppendIteratorTest::testAppendIterator with data set #1 (5)'. 
    R                 2/2 (100%) 
    test> 5 


    Time: 24 ms, Memory: 4.00MB 

    There were 2 risky tests: 

    1) AppendIteratorTest::testAppendIterator with data set #0 (4) 
    This test did not perform any assertions 

    2) AppendIteratorTest::testAppendIterator with data set #1 (5) 
    This test did not perform any assertions 

    OK, but incomplete, skipped, or risky tests! 
    Tests: 2, Assertions: 0, Risky: 2. 

回答

0

難道我設置的東西錯了,或者可以AppendIterators不能作爲PHPUnit的數據提供者?

錯誤的分類。數據提供商PHPUnit中支持任何arrayTraversableAppendIteratorTraversable)。所以它確實有效(你可以看到這一點,因爲你沒有得到一個錯誤)。

然而,數據提供者有一個(鮮爲人知的)細節:每個數據集可以有一個名稱名稱是提供的陣列的關鍵 - 或者 - 在Traversable的值爲Iterator::key()。對於數組鍵爲ArrayIterator

這裏的鑰匙你的代碼是可見的PHP創建它們含蓄:

$iterator->append(new ArrayIterator([0 => [0], 1 => [1]])); 
    $iterator->append(new ArrayIterator([0 => [2], 1 => [3]])); 
    $iterator->append(new ArrayIterator([0 => [4], 1 => [5]])); 

在您的鑰匙,這些將永遠是0和1。當你有重複鍵,最後的將「贏」。這是你看到的結果。

這是一個解釋發生了什麼。然後

一種解決方案可能是:

$iterator->append(new ArrayIterator([0 => [0], 1 => [1]])); 
    $iterator->append(new ArrayIterator([2 => [2], 3 => [3]])); 
    $iterator->append(new ArrayIterator([4 => [4], 5 => [5]])); 

PHP中沒有默認的迭代器這將重號的鑰匙,我也沒有一個在Iterator GardenIndexingIterator接近,伯格斯例子下降,Nikic iter lib's reindex可以做到這一點,...)在你的情況下,快速的在線將收益重新索引:

public function getAppendIterator() { 
    $iterator = new AppendIterator(); 
    $iterator->append(new ArrayIterator([[0], [1]])); 
    $iterator->append(new ArrayIterator([[2], [3]])); 
    $iterator->append(new ArrayIterator([[4], [5]])); 

    $index = 0; 
    foreach ($iterator as $i) { 
     yield $index++ => $i; 
    } 
} 

這裏$index計數器用作關鍵在yield聲明中。這使您的數據提供商返回Generator,這是一個Traversable再次。 Phpunit然後可以處理它。

的問題是類似的,當你有多個數據提供商的方法,只要使用字符串鍵返回數據集。所有字符串鍵都必須是唯一的,否則所提供的數據將被重寫。

即B/C內部的數據集從每個數據提供商變成數組明確。

我希望這回答了你的問題,還可以幫助你創建你正在尋找的數據提供商。

+0

THANKS @hakre!現在我讀了你的答案,這是完全合理的。 – Shawn