我是单元测试的新手,我在phpunit中理解模拟对象时遇到了问题.我有以下功能:
public function createPaymentStatement()
{
$tModel = new \FspInvoice\Model\Transaction();
$paymentsArr = $this->transactionGateway->getTransactionWithStatus($tModel::SETTLED);
$result = false;
if(is_array($paymentsArr)){
//some code here
$result = $psArr;
}
return $result;
}
Run Code Online (Sandbox Code Playgroud)
现在上面的函数的单一测试:
public function testCreatePaymentStatementWithPaymentsSettledReturnsArray()
{
$this->transactionGateway = $this->getMockBuilder('FspInvoice\Model\TransactionsTable')
->setMethods(array('getTransactionWithStatus'))
->disableOriginalConstructor()
->getMock();
$this->transactionGateway->expects($this->once())
->method('getTransactionWithStatus')
->will($this->returnValue(array(0,1,2)));
$test = $this->service->createPaymentStatement();
$this->assertTrue(is_array($test));
}
Run Code Online (Sandbox Code Playgroud)
但是当我运行代码时,我得到错误:
1)FspInvoiceTest\ServiceTest\PaymentTest::testCreatePaymentStatementWithPaymentsSettledReturnsArray
Expectation failed for method name is equal to <string:getTransactionWithStatus> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
我正在尝试减少程序的依赖性,使其更容易测试.我这样做的一个实例是我__construct()的一个类的方法.之前,它曾经接受一个文件名,然后该__construct()方法将使用该文件名将file_get_contents()内容保存到属性中:
public function __construct($name){
$this->name = $name;
$this->contents = file_get_contents($name);
}
Run Code Online (Sandbox Code Playgroud)
为了减少对文件系统的依赖,我将其替换为:
public function __construct(SplFileObject $file){
$this->name = $file->getFilename();
$this->contents = '';
while(!$file->eof()){
$this->contents .= $file->fgets();
}
}
Run Code Online (Sandbox Code Playgroud)
我相信这更容易测试,因为我可以模拟一个SplFileObject(可以设置为包含我想要的任何内容)并传入它.到目前为止我看到的例子包括做这样的事情:
$stub = $this->getMock('SplFileObject');
$stub->expects($this->any())
->method('fgets')
->will($this->returnValue('contents of file'));
Run Code Online (Sandbox Code Playgroud)
然而,意志的模拟fgets方法SplFileObject需要更复杂 - 它需要遍历内容的每一行,并在它到达结束时停止.
暂时我有一个有效的解决方案 - 我刚刚创建了一个全新的类MockSplFileObject来覆盖这些方法:
class MockSplFileObject extends SplFileObject{
public $maxLines;
public $filename;
public $contents;
public $currentLine = 1;
public function __construct($filename, $contents){
$this->filename = $filename;
$this->contents = …Run Code Online (Sandbox Code Playgroud) 我试图通过Composer将PHPUnit安装到Laravel框架中.
问题是运行composer update后未下载所需的文件.
我的流程如下:
首先,我在中插入PHPUnit要求composer.json.整个文件看起来像这样:
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"laravel/framework": "4.1.*",
"laravelbook/ardent": "dev-master",
"phpunit/phpunit": "4.2.*" // i have also tried with 3.7 and 3.8
},
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/filters"
]
},
"scripts": {
"post-install-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-update-cmd": [
"php artisan clear-compiled",
"php artisan optimize"
],
"post-create-project-cmd": [
"php artisan …Run Code Online (Sandbox Code Playgroud) 我正在使用PHPUnit来测试PHP函数的输出,该函数option使用提供的数据生成HTML 标记.
例如,这是函数的正确输出(我添加了行返回以提高SO的可读性):
<option value="0">Choose one ...</option>
<option value="fooID">fooValue</option>
<option value="barID"selected>barValue</option>
<option value="bazID">bazValue</option>
Run Code Online (Sandbox Code Playgroud)
为了测试输出,我正在使用这个断言:
$this->assertRegExp("/(<option value=\".*\" *(selected)? *>.*<\/option>)+/i", $res);
Run Code Online (Sandbox Code Playgroud)
where $res测试函数的输出字符串.
它运作良好.但我还要检查selected是否只在一个option标签中生成.
我怎样才能做到这一点?有没有办法计算selected匹配的次数?
提前谢谢,善待,这是我关于SO的第一个问题:-)
我想使用composer生成的自动加载器为我的单元测试自动加载类.
现在我不知道是否应该将我的供应商目录提交到我的git repo.一个专家是每个立即克隆我的仓库的人都可以运行phpUnit测试.一个骗局是我用我的仓库运送了很多专有代码.
我是否应该坚持克隆我的仓库的用户必须先运行composer install,因此必须"安装"作曲家?
这是一个解决方案,不将供应商目录提交到我的git仓库,但将其打包到一个发布分支,以便我的应用程序开箱即用?
我知道截图可以通过扩展来实现,PHPUnit_Extensions_Selenium2TestCase但是现在,我正在使用Facebook的php-webdriver所以我只是延伸PHPUnit_Framework_TestCase
无论如何,只有驱动程序而不是扩展扩展名才能截取屏幕截图?
谢谢.
我在测试脚本中设置了一个PDO连接:
use app\SomeDAO;
class SomeTest extends \PHPUnit_Framework_TestCase
{
protected $db;
public function setUp()
{
$dsn = "mysql:host=localhost;dbname=baseball;user=root;password=root";
$this->db = new PDO($dsn);
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误:
PDOException:SQLSTATE [HY000] [2002]没有这样的文件或目录.
我如何在这里使用PDO?
我正试图为我的RESTful api函数提取一些测试.
为此,我做了以下事情:
我的问题是:
执行请求时(somedomain.com/api/somemethod) - >请求的页面不知道我正在对它执行测试 - >所以它使用的数据是生产/开发数据库而不是'test'db我已经为测试创建了.
(该脚本使用测试db,请求的页面使用正常配置).
有没有办法在不触及或修改API代码/行为的情况下解决它?
谢谢.
我刚刚开始使用PHPUnit并且可以使用所有的assert*方法,但是无法弄清楚当向方法提供错误的参数时如何测试错误抛出 - 比如暗示array如下:
public function(array $list) { }
Run Code Online (Sandbox Code Playgroud)
然后用nullas参数进行测试.
有人可以提供一个如何测试这种错误的例子吗?
我在stackoverflow上查了不少帖子,但找不到这个特定问题的答案.
编辑
好的 - 只是为了让您了解我正在测试的内容 - 这里是ArrayHelper :: removeIfValueIsEmpty()方法:
public static function removeIfValueIsEmpty(array $array) {
if (empty($array)) {
return array();
}
return array_filter($array, function($value) {
return !Helper::isEmpty($value);
});
}
Run Code Online (Sandbox Code Playgroud)
现在测试:
class ArrayHelperTest extends PHPUnit_Framework_TestCase {
public function testRemoveIfValueIsEmpty() {
$this->assertEmpty(
\Cmd\Helper\ArrayHelper::removeIfValueIsEmpty(null),
'\Cmd\Helper\ArrayHelper::removeIfValueIsEmpty method failed (checking with null as argument)'
);
}
}
Run Code Online (Sandbox Code Playgroud)
这会引发错误:
PHPUnit_Framework_Error : Argument 1 passed to Cmd\Helper\ArrayHelper::removeIfValueIsEmpty() must be of the type array, …Run Code Online (Sandbox Code Playgroud) 我想在Symfony 2.3.24/Windows7/PHP 5.4.7下熟悉测试(单元,功能).
似乎PHPUnit安装正确(通过Composer),但是当我运行phpunit -c app/命令时,我收到以下错误:
Warning: require_once(PHP/CodeCoverage/Filter.php): failed to open stream: No such file or directory in C:\xampp\php\phpunit on line 38
Fatal error: require_once(): Failed opening required 'PHP/CodeCoverage/Filter.php' (include_path='.;C:\xampp\php\PEAR') in C:\xampp\php\phpunit on line 38
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索这个问题无济于事.我另外在官方的PHPUnit网站上找到了The code coverage report feature requires the Xdebug (2.1.3 or later) and tokenizer extensions.
你怎么看待这一切?非常感谢您的帮助.