SQLite(php)fetchArray()不会在结果结束时停止

时间:2017-05-24 21:07:58

标签: php sqlite phpunit

我正在尝试测试我的一些模型。我使用依赖注入来选择数据库方法。我已经有了工作模型,但我想回去做测试,这样我才能开始工作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.

1 个答案:

答案 0 :(得分:0)

在您的抽象类中,您将显式地将数据库返回的值强制转换为对象。因此,即使它是false,在将其转换为对象之后,该值也不会是&#34; falsy&#34;。这使循环无限运行。

您需要修复的代码位于fetchObject方法:

return (object)($this->result->fetchArray());

将其更改为

$res = $this->result->fetchArray();
if (!$res)
    return $res;
return (object)$res;