2012-05-18 2 views
4

Я написал случай DataTest, следующий за примером 4.5 руководства PHPUnit, URL-адрес:
http://www.phpunit.de/manual/3.6/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers.
Но я наткнулся с ошибкой:Как использовать файл csv в PHPUnit test

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), чтобы использовать путь include. – 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

Большое вам спасибо за ответ, я попробую еще раз, и он работает. Но у меня все еще есть вопрос, почему я не могу использовать 'return new CsvFileIterator ('csv file name');' в функции provider(), как и в примере 4.5. [link] http://www.phpunit.de/manual/3.6/ru/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'); 
} 
Смежные вопросы