From e53a91fe8c460434e3d5e422bab46559963592c2 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Tue, 14 Aug 2007 01:42:55 +0000 Subject: [PATCH] Adding database unit tests and in the Db module, use a new DatabaseException class intead of triggering errors --- Db.php | 70 ++++++----- DbMySql.php | 1 + docs/UnitTest/AllTests.php | 3 + docs/UnitTest/DatabaseMySQLTest.php | 43 +++++++ docs/UnitTest/DatabaseMySQLiTest.php | 43 +++++++ docs/UnitTest/DatabaseTestAbstract.php | 167 +++++++++++++++++++++++++ docs/UnitTest/DatabaseTests.php | 40 ++++++ docs/UnitTest/tests.config.php.new | 12 ++ 8 files changed, 351 insertions(+), 28 deletions(-) create mode 100644 docs/UnitTest/DatabaseMySQLTest.php create mode 100644 docs/UnitTest/DatabaseMySQLiTest.php create mode 100644 docs/UnitTest/DatabaseTestAbstract.php create mode 100644 docs/UnitTest/DatabaseTests.php diff --git a/Db.php b/Db.php index e39addd..9450351 100644 --- a/Db.php +++ b/Db.php @@ -117,7 +117,7 @@ abstract class BSDb if ($this->dblink == false) { - $this->_error('DB-Link == false, cannot connect'); + throw new BSDbException('Connect Failed', -1, 'DB-Link == false; connect failed'); return false; } @@ -155,7 +155,7 @@ abstract class BSDb if (!$this->result) { - $this->_error('Invalid SQL query'); + throw new BSDbException($this->_errorString(), $this->_errorNumber(), $string); } $this->history[] = $history = array('query' => $string, 'time' => BSFunctions::FetchMicrotimeDiff($time), 'trace' => BSFunctions::FormatBacktrace(debug_backtrace())); @@ -449,36 +449,50 @@ abstract class BSDb * should never be reached as it's always overridden */ public abstract function transactionCommit(); +} + +/** + * Database Exception + * + * Exception handler class for the database classes + * + * @author Blue Static + * @copyright Copyright (c)2002 - [#]year[#], Blue Static + * @version $Id$ + * @package ISSO + * + */ +class BSDbException extends Exception +{ + /** + * The query string that caused the error + * @var string + */ + private $query; // ################################################################### /** - * Error wrapper for ISSO->message() - * - * @param string User defined error message - */ - protected function _error($message) + * Initializes a new database exception + * + * @param string The error message + * @param ineger MySQL error code + * @param sring Query string that caused the error + */ + public function __construct($error, $errorNum, $query) { - if ($this->showerrors) - { - if ($this->dblink) - { - $this->errnum = $this->_errorNumber(); - $this->errstr = $this->_errorString(); - } - - $style['code'] = 'font-family: \'Courier New\', Courier, mono; font-size: 11px;'; - - $message_prepped = "
\n

"; - $message_prepped .= "\n\t» Query:\n

" . htmlspecialchars($this->querystr) ."
\n
"; - $message_prepped .= "\n\t» Error Number: " . $this->errnum . "\n
"; - $message_prepped .= "\n\t» Error Message: " . $this->errstr . "\n
"; - $message_prepped .= "\n\t» Additional Notes: " . $message . "\n
"; - $message_prepped .= "\n\t» File: " . $_SERVER['PHP_SELF'] . "\n"; - $message_prepped .= "\n

\n
"; - - BSRegister::Message('Database Error in `' . BSRegister::GetApplication() . '`', $message_prepped, 3); - exit; - } + $this->query = $query; + parent::__construct($error, $errorNum); + } + + // ################################################################### + /** + * Returns the query that failed + * + * @return string + */ + public function getQuery() + { + return $this->query; } } diff --git a/DbMySql.php b/DbMySql.php index c009152..80c6fb4 100644 --- a/DbMySql.php +++ b/DbMySql.php @@ -67,6 +67,7 @@ class BSDbMySql extends BSDb { if (!mysql_select_db($database, $link)) { + throw new BSDbException($this->_errorString(), $this->_errorNumber(), 'Cannot use the database ' . $database); $this->_error('Cannot use the database "' . $database . '"'); } } diff --git a/docs/UnitTest/AllTests.php b/docs/UnitTest/AllTests.php index 9444f56..6bb6bb0 100644 --- a/docs/UnitTest/AllTests.php +++ b/docs/UnitTest/AllTests.php @@ -37,6 +37,9 @@ class AllTests require_once 'XmlTest.php'; $suite->addTestSuite('XmlTest'); + require_once 'DatabaseTests.php'; + $suite->addTestSuite(DatabaseTests::suite()); + return $suite; } } diff --git a/docs/UnitTest/DatabaseMySQLTest.php b/docs/UnitTest/DatabaseMySQLTest.php new file mode 100644 index 0000000..0825de6 --- /dev/null +++ b/docs/UnitTest/DatabaseMySQLTest.php @@ -0,0 +1,43 @@ +fixture = BSRegister::LoadModule('DbMySql'); + $this->fixture->connect(TEST_DB_MYSQL_HOST, TEST_DB_MYSQL_USER, TEST_DB_MYSQL_PASSWORD, TEST_DB_MYSQL_DATABASE); + $this->fixture->query(" + CREATE TABLE test + ( + id int auto_increment, + textstuff varchar(255), + PRIMARY KEY (id) + ) + "); + } + + public function tearDown() + { + $this->fixture->query("DROP TABLE test"); + $this->fixture = null; + } + + public function testConnect() + { + try + { + BSRegister::LoadModule('DbMySql')->connect('localhost', '--invalid user--', '--invalid password--', '--nodatabase--'); + $this->fail('exception expected'); + } + catch (BSDbException $e) + {} + } +} + +?> \ No newline at end of file diff --git a/docs/UnitTest/DatabaseMySQLiTest.php b/docs/UnitTest/DatabaseMySQLiTest.php new file mode 100644 index 0000000..86e2513 --- /dev/null +++ b/docs/UnitTest/DatabaseMySQLiTest.php @@ -0,0 +1,43 @@ +fixture = BSRegister::LoadModule('DbMySqlI'); + $this->fixture->connect(TEST_DB_MYSQL_HOST, TEST_DB_MYSQL_USER, TEST_DB_MYSQL_PASSWORD, TEST_DB_MYSQL_DATABASE); + $this->fixture->query(" + CREATE TABLE test + ( + id int auto_increment, + textstuff varchar(255), + PRIMARY KEY (id) + ) + "); + } + + public function tearDown() + { + $this->fixture->query("DROP TABLE test"); + $this->fixture = null; + } + + public function testConnect() + { + try + { + BSRegister::LoadModule('DbMySqlI')->connect('localhost', '--invalid user--', '--invalid password--', '--nodatabase--'); + $this->fail('exception expected'); + } + catch (BSDbException $e) + {} + } +} + +?> \ No newline at end of file diff --git a/docs/UnitTest/DatabaseTestAbstract.php b/docs/UnitTest/DatabaseTestAbstract.php new file mode 100644 index 0000000..31f57a9 --- /dev/null +++ b/docs/UnitTest/DatabaseTestAbstract.php @@ -0,0 +1,167 @@ +fixture->query("INSERT INTO test (textstuff) VALUES ('moo'), ('foo'), ('hey'), ('foo'), ('boo'), ('poo')"); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + + try + { + $res = $this->fixture->query("SELECT * FROM test WHERE textstuff = 'foo'"); + + $row = $this->fixture->fetchArray($res); + $this->assertNotNull($row['textstuff']); + + $row = $this->fixture->fetchArray($res); + $this->assertNotNull($row['textstuff']); + + $row = $this->fixture->fetchArray($res); + $this->assertNull($row['textstuff']); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + } + + public function testEscapeString() + { + $this->assertEquals("Robert\'s castle", $this->fixture->escapeString("Robert's castle")); + } + + public function testFetchObject() + { + try + { + $this->fixture->query("INSERT INTO test (textstuff) VALUES ('foo')"); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + + try + { + $res = $this->fixture->query("SELECT * FROM test"); + $obj = $this->fixture->fetchObject($res); + + $this->assertNotNull($obj); + $this->assertEquals('foo', $obj->textstuff); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + } + + public function testQueryFirst() + { + try + { + $this->fixture->query("INSERT INTO test (textstuff) VALUES ('abc'), ('123'), ('def')"); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + + try + { + $res = $this->fixture->queryFirst("SELECT * FROM test ORDER BY id DESC"); + $this->assertEquals('def', $res['textstuff']); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + } + + public function testInsertId() + { + try + { + $this->fixture->query("INSERT INTO test (textstuff) VALUES ('abc')"); + $this->assertEquals(1, $this->fixture->insertId('test', 'textstuff')); + + $this->fixture->query("INSERT INTO test (textstuff) VALUES ('123')"); + $this->assertEquals(2, $this->fixture->insertId('test', 'textstuff')); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + } + + public function testNumRows() + { + try + { + $this->fixture->query("INSERT INTO test (textstuff) VALUES ('123'), ('456'), ('789')"); + + $res = $this->fixture->query("SELECT * FROM test"); + $this->assertEquals(3, $this->fixture->numRows($res)); + + $res = $this->fixture->query("SELECT * FROM test WHERE textstuff = '--invalid value--'"); + $this->assertEquals(0, $this->fixture->numRows($res)); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + } + + public function testAffectedRows() + { + try + { + $this->fixture->query("INSERT INTO test (textstuff) VALUES ('123'), ('456'), ('123')"); + + $res = $this->fixture->query("UPDATE test SET textstuff = 'abc' WHERE textstuff = '123'"); + $this->assertEquals(2, $this->fixture->affectedRows($res)); + + $res = $this->fixture->query("SELECT * FROM test WHERE textstuff = 'abc'"); + $this->assertEquals(2, $this->fixture->numRows($res)); + } + catch (BSDbException $e) + { + $this->fail('unexpected exception'); + } + } + + public function testInvalidQuery() + { + try + { + $this->fixture->query("SELECT * FROM foobar"); + $this->fail('exception expected'); + } + catch (BSDbException $e) + { + $this->assertEquals('SELECT * FROM foobar', $e->getQuery()); + } + } +} + +?> \ No newline at end of file diff --git a/docs/UnitTest/DatabaseTests.php b/docs/UnitTest/DatabaseTests.php new file mode 100644 index 0000000..c131e99 --- /dev/null +++ b/docs/UnitTest/DatabaseTests.php @@ -0,0 +1,40 @@ +addTestSuite('DatabaseMySQLTest'); + + require_once 'DatabaseMySQLiTest.php'; + $suite->addTestSuite('DatabaseMySQLiTest'); + + return $suite; + } +} + +if (PHPUnit_MAIN_METHOD == 'DatabaseTests') +{ + DatabaseTests::main(); +} + +?> \ No newline at end of file diff --git a/docs/UnitTest/tests.config.php.new b/docs/UnitTest/tests.config.php.new index 9bdf099..f542215 100644 --- a/docs/UnitTest/tests.config.php.new +++ b/docs/UnitTest/tests.config.php.new @@ -22,6 +22,18 @@ // path to the directory that holds ISSO define('TEST_PATH_TO_ISSO', '/usr/local/apache2/htdocs'); +// mysql database username +define('TEST_DB_MYSQL_USER', 'mysql'); + +// mysql database password +define('TEST_DB_MYSQL_PASSWORD', 'foo'); + +// mysql database hostname +define('TEST_DB_MYSQL_HOST', 'localhost'); + +// mysql database to use +define('TEST_DB_MYSQL_DATABASE', 'issotest'); + /*=====================================================================* || ################################################################### || # $HeadURL$ -- 2.43.5