我在试着测试我的一些模特。我使用依赖注入来选择数据库方法。我已经有了工作模型,但我试图回去做测试,这样我就可以开始做TDD而不是希望和祈祷.
不过,在开始测试我的模型之前,我必须先验证我的数据库抽象。我为SQLite3编写了一个抽象,以模仿我为ODBC使用的抽象。我的计划是使用SQLite测试我的模型。
我很难弄清楚为什么
while循环在testDbSqLiteFetchObjectImplementation2()中永不停止。在对结果进行迭代时,$this->abstraction->fetchObject()应该返回false。但是它试图继续运行,这会引发一个未定义的属性错误。
)任何不返回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.发布于 2017-05-24 23:39:50
在抽象类中,您要显式地将数据库返回的值转换为对象。因此,即使它是false,在将其转换为object之后,它的值也不会是"falsy“。这使得循环无限地运行。
您需要修复的代码在fetchObject方法中:
return (object)($this->result->fetchArray());将其改为类似的
$res = $this->result->fetchArray();
if (!$res)
return $res;
return (object)$res;https://stackoverflow.com/questions/44168487
复制相似问题