我正在使用 PHP CodeIgniter 框架编写一个应用程序。我正在尝试使用 CI_Unit(扩展名为 PHPUnit)来测试应用程序。为了测试模型,我尝试加载 PHPUnit 文档中定义的 YAML 数据提供程序,但收到错误。如果我伪造数据提供者对象,则会收到另一个错误。如果我向它提供一个普通的 PHP 数组,它就会按预期运行。
我做错了什么?这样做的正确方法是什么?以下是我的结果:
如果我返回下面 Yaml 文件的对象
PHPUnit_Extensions_Database_DataSet_YamlDataSet
,我会得到:
数据集“Clients”无效。
如果我循环
PHPUnit_Extensions_Database_DataSet_YamlDataSet
返回的对象并返回:我收到此错误:
PHPUnit_Framework_Exception:“models.php”和“models.php”都无法打开。在 /Users/eric/pear/share/pear/PHPUnit/Util/Skeleton/Test.php 第 100 行
如果我为它提供一个普通的 PHP 数组,测试就可以正常运行。我用来运行测试的命令是:
phpunit 模型
下面是我的 YAML 文件的示例。
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
我正在使用 PHP 5.3、PHPUnit 3.6.10、DBUnit 1.1.2、CodeIgniter 2.1.0 以及与 CI 2.1.0 相关的 CI_unit。
编辑: 附件是我的 models/Test.php 文件:
/**
* 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;
}
如 PHPUnit 文档中关于 Data Providers 的描述:
数据提供者方法必须是
并且返回一个数组 数组或实现public
接口并产生的对象 每个迭代步骤的数组。对于属于其中的每个数组 集合将使用以下内容调用测试方法 数组作为其参数。Iterator
根据您的
Test.php
源代码,您似乎想要这样的东西:
/**
* 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;
}
似乎 PHPUnit 应该提供一个函数来将数据集表直接转换为数组数组,但我快速浏览了一下,并没有看到任何东西。
据我所知,
phpunit.xml
文件无关紧要,可以从您的问题中删除。
您也不需要 PHPUnit 测试方法中的
try/catch
块 - PHPUnit 会为您处理这个问题。
请注意,您的
$company_id
未定义,所以我只是将其设置为 0。上面的方法参数和 YAML 数据似乎也不完全匹配,但这应该很容易修复。
通过将数组传递到测试函数,该函数会立即传递到
add_client
方法,您的代码也更加干燥。
PHPUnit 提供商自动加载器
在 PHPUnit 中自动加载 CSV、JSON、PHP、XML 和 YAML 数据提供程序的神奇助手。
安装
composer require henryruhs/phpunit-provider-autoloader
用法
为您的测试套件创建 TestCaseAbstract:
<?php
namespace ExampleProject\Tests;
use PHPUnitProviderAutoloader;
/**
* TestCaseAbstract
*
* @since 2.0.0
*
* @package ExampleProject
* @category Tests
*/
abstract class TestCaseAbstract extends PHPUnitProviderAutoloader\TestCaseAbstract
{
/**
* directory of the provider
*
* @var string
*/
protected $_providerDirectory = 'tests' . DIRECTORY_SEPARATOR . 'provider';
/**
* namespace of the testing suite
*
* @var string
*/
protected $_testNamespace = __NAMESPACE__;
}
从 TestCaseAbstract 扩展以自动加载 ExampleTest{_testMethod}.{csv|json|php|xml|yml} 文件:
<?php
namespace ExampleProject\Tests;
/**
* ExampleTest
*
* @since 2.0.0
*
* @package ExampleProject
* @category Tests
*/
class ExampleTest extends TestCaseAbstract
{
/**
* testMethod
*
* @since 2.0.0
*
* @param string $expect
*
* @dataProvider providerAutoloader
*/
public function testMethod(string $expect = null)
{
$this->assertEquals($expect, 'test');
}
}
了解更多
相关存储库:https://github.com/henryruhs/phpunit-provider-autoloader
集成示例:YAML 测试自动加载YAML 类提供程序和YAML 方法提供程序