2012-05-18 54 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'); 
}