2012-05-18 164 views
4

使用CSV文件,我下面的例子PHPUnit的4.5手動的,網址是寫了一個數據測試的情況。
但我有一個錯誤遇到:如何在PHPUnit的測試

The data provider specified for DataTest::testAdd is invalid.
Data set #0 is invalid.

我想這也許是我在一個錯誤的方式編輯data.csv文件,然後我用PHP函數fputcsv()創建data.csv文件,但它也沒有工作,我想知道爲什麼,以及如何解決這個問題。謝謝!

PS:在data.csv的數據是:

0,0,0
0,1,1


的代碼是顯示如下:
DataTest.php

require 'CsvFileIterator.php'; 
class DataTest extends PHPUnit_Framework_TestCase 
{ 
public function provider() 
    { 
     return new CsvFileIterator('data.csv'); 
    } 

    /** 
    * @dataProvider provider 
    */ 
    public function testAdd($a, $b, $c) 
    { 
     $this->assertEquals($c, $a + $b); 
    } 
} 

CsvFileIterator.php

class CsvFileIterator implements Iterator 
{ 
    protected $file; 
    protected $key = 0; 
protected $current; 

public function __construct($file) 
{ 
    $this->file = fopen($file, 'r'); 
} 

public function __destruct() 
{ 
    fclose($this->file); 
} 

public function rewind() 
{ 
    rewind($this->file); 
    $this->current = fgetcsv($this->file); 
    $this->key = 0; 
} 

public function valid() 
{ 
    return !feof($this->file); 
} 

public function key() 
{ 
    return $this->key; 
} 

public function current() 
{ 
    return $this->current; 
} 

public function next() 
{ 
    $this->current = fgetcsv($this->file); 
    $this->key++; 
} 
} 

的data.csv文件是功能fputcsv()創建:

$data = array(
array(0, 0, 0), 
array(0, 1, 1) 
); 

$fp = fopen('data.csv', 'w'); 

foreach($data as $v) 
{ 
fputcsv($fp, $v); 
} 
fclose($fp); 
+1

請出示您的數據提供程序函數的代碼。解釋你犯錯的地方很重要。通過編輯將其添加到您的問題中(您可以縮短文件名和其他不重要的文件名和其他特定數據以便了解您的問題)。 – hakre

+0

@hakre,我已經在我的問題中添加了代碼,請幫我分析並告訴我爲什麼會出現錯誤,謝謝! –

+0

檢入你的迭代器可以訪問文件的構造函數。例如,您可能需要將其傳遞到完整路徑(例如'__DIR__。'/ data.csv')。或者,使用'true'作爲[fopen的第三個參數](http://uk3.php.net/manual/en/function.fopen.php)來使用包含路徑。 – cmbuckley

回答

5

例:-)

/** 
* @dataProvider provider 
* @group csv 
*/ 
public function testAdd($a, $b, $c) 
{ 
    $this->assertEquals($c, $a + $b); 
} 

/** 
* @return array 
*/ 
public function provider() 
{ 
    $file = file_get_contents("/Volumes/htdocs/contacts.csv","r"); 
    foreach (explode("\n", $file, -1) as $line) 
    { 
     $data[] = explode(',', $line); 
    } 
    return $data; 
} 

/* 
* CREATE TO CSV FILE DATAPROVIDER 
* don't create this file in your test case 
*/ 
public function saveToCsv() 
{ 
    $list = array(
     array(0,0,0), 
     array(0,1,1) 
    ); 

    $file = fopen("/Volumes/htdocs/contacts.csv","w"); 

    foreach ($list as $line) 
    { 
     fputcsv($file,$line); 
    } 

    fclose($file); 
} 
+1

非常感謝你的回覆,我再試一次,它的工作原理。但是我仍然有一個問題,爲什麼我不能像例子4.5那樣在函數provider()中使用'return new CsvFileIterator('csv file name');''。 [鏈接] http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers –

+0

@ZongshuLin類似的問題在這裏。檢查這[data.csv](https://github.com/rdok/phpunit.de/blob/02-writing-tests-for-phpunit/storage/data.csv),以及我的[方法](https ://github.com/rdok/phpunit.de/blob/02-writing-tests-for-phpunit/tests/IteratorObjectDataProviderTest.php)指定data.csv的位置。 – rdok

0

@ZongshuLin類似這裏的問題。可能的解決方案:

  • 檢查data.csv。基本上我必須在最後一行之後添加一行。
  • 您還可以檢查我的approach on GitHub指定data.csv位置時

Use DIRECTORY_SEPARATOR constant so the script may run on any OS--Windows uses backslashes while Linux slashes.

/** 
* @return CsvFileIterator 
*/ 
public function additionProvider() 
{ 
    return new CsvFileIterator(__DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'storage/data.csv'); 
}