我正在尝试测试我的一些模型。我使用依赖注入来选择数据库方法。我已经有了工作模型,但我想回去做测试,这样我才能开始工作TDD而不是希望和祈祷......
在我开始测试我的模型之前,我必须证明我的数据库抽象。我为SQLite3编写了一个抽象来模仿我用于ODBC的抽象。我的计划是使用SQLite来测试我的模型。
我无法弄清楚是
while
循环的原因testDbSqLiteFetchObjectImplementation2()
永不停止。$this->abstraction->fetchObject()
应该返回false
完成迭代结果。但它试图继续进行抛出未定义的属性错误。
任何有关它不会返回虚假的想法都值得赞赏:)
db_sqlite.class.php
<?php
/**
* SQLite Database Abstraction
*
* This class is a database abstraction that allows consistent and simplified methods for
* accessing databases, along with db_db2.class.php and db_odbc.class.php
**/
class DB_sqlite {
public function __construct($database = "", $user = "", $password = "") {
$this->db = new SQLite3(':memory:');
}
public function prepare($query) {
$this->statement = $this->db->prepare($query);
}
public function bind($vals='') {
settype($vals, 'array');
for($i=0; $i<sizeof($vals); $i++) {
$this->statement->bindValue(($i+1), $vals[$i]); // bindValue index starts at 1, not 0
}
$this->result = $this->statement->execute();
return $this->result;
}
/**
* OOP method for retrieving a row of db. Use in a while statement that assigns results to a var, ie
*
* while($row = $db->fetchObject()) {
* print $row->COLUMN_NAME;
* }
*
* @return object Typically the returned object's properties must be accessed as ALL CAPS
*/
public function fetchObject() {
return (object)($this->result->fetchArray());
}
/**
* Associative Array method of retrieving row
*/
public function fetchRow() {
return $this->result->fetchArray(SQLITE3_ASSOC);
}
sampleTest.php
use PHPUnit\Framework\TestCase;
require("../scripts/task_config.php");
class sampleTest extends TestCase {
public function setupDb() {
$this->abstraction = new db_sqlite;
$fields = 'HISTID NUMERIC,ORGID NUMERIC,STATUS TEXT';
// note $this->abstraction calls db_sqlite's 'db' property
// which is a `new SQLite3(':memory:')` object
$this->abstraction->db->exec("CREATE TABLE tableName ($fields)");
$this->abstraction->db->exec("INSERT INTO tableName (HISTID,ORGID,STATUS) VALUES (1, 101, 'c')");
$this->abstraction->db->exec("INSERT INTO tableName (HISTID,ORGID,STATUS) VALUES (2, 102, 'c')");
}
public function testDbSqLiteFetchRowImplementation() {
$this->setupDb();
$this->abstraction->prepare("SELECT * FROM tableName WHERE STATUS='c'");
$this->abstraction->bind();
$row = $this->abstraction->fetchRow();
$this->assertEquals('101', $row['ORGID']);
$row = $this->abstraction->fetchRow();
$this->assertEquals('102', $row['ORGID']);
}
public function testDbSqLiteFetchObjectImplementation() {
$this->setupDb();
$this->abstraction->prepare("SELECT * FROM tableName WHERE STATUS='c'");
$this->abstraction->bind(); // db abstraction binds and executes.
$row = $this->abstraction->fetchObject();
$this->assertEquals('101', $row->ORGID);
$row = $this->abstraction->fetchObject();
$this->assertEquals('102', $row->ORGID);
}
public function testDbSqLiteFetchObjectImplementation2() {
$this->setupDb();
$this->abstraction->prepare("SELECT * FROM tableName WHERE STATUS='c'");
$this->abstraction->bind();
$count = 0;
print "\n";
while($row = $this->abstraction->fetchObject()) {
print ++$count;
$collection[] = $row->ORGID;
}
$this->assertEquals('101', $collection[0]);
$this->assertEquals('102', $collection[1]);
}
}
测试结果
$ cmd //c phpunit
PHPUnit 6.0.10 by Sebastian Bergmann and contributors.
..E 3 / 3 (100%)
Number of while loop iterations:
123
Time: 339 ms, Memory: 10.00MB
There was 1 error:
1) sampleTest::testDbSqLiteFetchObjectImplementation2
Undefined property: stdClass::$ORGID
X:\tests\sample2Test.php:66
ERRORS!
Tests: 3, Assertions: 4, Errors: 1.
答案 0 :(得分:0)
在您的抽象类中,您将显式地将数据库返回的值强制转换为对象。因此,即使它是false
,在将其转换为对象之后,该值也不会是&#34; falsy&#34;。这使循环无限运行。
您需要修复的代码位于fetchObject
方法:
return (object)($this->result->fetchArray());
将其更改为
$res = $this->result->fetchArray();
if (!$res)
return $res;
return (object)$res;