Using YAML Files as data provider in PHPUnit (CIUnit)
codeigniter, php, phpunit, yaml
Solution
As described in the PHPUnit documentation on Data Providers:
A data provider method must be `public` and either return an array of arrays or an object that implements the `Iterator` interface and yields an array for each iteration step. For each array that is part of the collection the test method will be called with the contents of the array as its arguments.
Based on your `Test.php` source code, it seems you want something like this:
/**
* test_add_client
* @dataProvider add_client_provider
*/
public function test_add_client($data)
{
$company_id = 0;
$id = $this->_m->add_client($company_id, $data);
$this->assertEquals(true, is_int($id));
}
public function add_client_provider()
{
$result = new PHPUnit_Extensions_Database_DataSet_YamlDataSet(
dirname(__FILE__)."/../fixtures/Clients.yml");
// Return the Clients data
$clients = array();
$tbl = $result->getTable('Clients');
for ($i = 0; $i < $tbl->getRowCount(); $i++) {
$clients[] = $tbl->getRow($i);
}
return $clients;
}
Seems PHPUnit should provide a function to turn a dataset table directly in to an array of arrays, but I didn't see anything after a quick glance.
The `phpunit.xml` file is irrelevant, and can be removed from your question, as far as I can tell.
You also don't need the `try/catch` block in the PHPUnit test method - PHPUnit will take care of that for you.
Note that your `$company_id` wasn't defined, so I just set it to 0. Your method arguments & YAML data above don't seem to match up fully above either, but that should be easy to fix.
By passing an array in to the test function, which gets passed immediately to the `add_client` method, your code is a bit more DRY as well.
Problem
I am writing an application using the PHP CodeIgniter Framework. I am trying to test the application using CI_Unit, by extension PHPUnit. To test a model, I am trying to load a YAML data provider as defined in the PHPUnit documentation, I receive an error. If I fudge the data provider object, I get another error. If I provide it a vanilla PHP array, it runs as expected. What am I doing wrong? What is the correct way to do this? Below are my results: If I return the object `PHPUnit_Extensions_Database_DataSet_YamlDataSet` of the Yaml file below, I get: Data set "Clients" is invalid. If I loop around the object returned by `PHPUnit_Extensions_Database_DataSet_YamlDataSet` and return that: I get this error: PHPUnit_Framework_Exception: Neither "models.php" nor "models.php" could be opened. in /Users/eric/pear/share/pear/PHPUnit/Util/Skeleton/Test.php on line 100 If I provide it a vanilla PHP array, the tests run just fine. The command I use to run the tests is: phpunit models Below is an example of my YAML file. ``` Clients: 1: client_id: 1 client_information: "info number 1" client_key: 48fb10b15f3d44a09dc82d 2: client_id: 2 client_information: "info number 2" client_key: 48fb10b15f3d44addd ``` I am using PHP 5.3, PHPUnit 3.6.10, DBUnit 1.1.2, CodeIgniter 2.1.0, and CI_unit associated with CI 2.1.0. Edit: Attached is my models/Test.php file: ``` /** * test_add_client * @dataProvider add_client_provider */ public function test_add_client($client_id,$company_id,$software_id,$client_information,$client_key) { $data = array('software_id' => $software_id, 'client_information' => $client_information, 'client_key' => $client_key); try { $id = $this->_m->add_client($company_id,$data); $this->assertEquals(true, is_int($id)); } catch (Exception $e){ $this->assertEquals(true,false); } } public function add_client_provider() { $result = new PHPUnit_Extensions_Database_DataSet_YamlDataSet( dirname(__FILE__)."/../fixtures/Clients.yml"); // Case #1 returns this $result //return $result; foreach($result as $key => $value){ if($key == 'Clients'){ $substructure = $value; } } // Case #2 return the inner structure that is the table return $substructure; // Case #3 return an array of arrays $data = array( array(1,1,1,'test','text 2'), array(1,2,1,'test 3', 'test 3')); return $data; } ```