Zend Framework

Error within unit testing with PHPUnit - Zend_Db_Table_Exception: No adapter found for [...]

Details

Description

I am using TDD with Zend Framework.

I've set up tests for every component of my application. Within testing, I am using an SQLite database that replaces the live database.

With 1.8.4, all went well.

With 1.9, I am getting random errors during testing, for example the following:

7) ModelTechnologyMapperTest::testFetchAll
Zend_Db_Table_Exception: No adapter found for Default_Model_DbTable_Technologies

/Users/skiller/PHP Projects/skiller/library/Zend/Db/Table/Abstract.php:754
/Users/skiller/PHP Projects/skiller/library/Zend/Db/Table/Abstract.php:739
/Users/skiller/PHP Projects/skiller/library/Zend/Db/Table/Abstract.php:268
/Users/skiller/PHP Projects/skiller/application/models/TechnologyMapper.php:17
/Users/skiller/PHP Projects/skiller/application/models/TechnologyMapper.php:32
/Users/skiller/PHP Projects/skiller/application/models/TechnologyMapper.php:52
/Users/skiller/PHP Projects/skiller/tests/application/models/TechnologyMapperTest.php:86

The strange thing is that other tests for model classes in the same test suite don't yield such errors although they share the exact same database and configuration parameters.

Since some tests work and some don't, I suspect a problem with the correct initiation sequence within the extended ZF/PHPUnit framework.

Activity

Hide
Dolf Schimmel (Freeaqingme) added a comment -

Could you please provide any code with which we can reproduce this problem?

Show
Dolf Schimmel (Freeaqingme) added a comment - Could you please provide any code with which we can reproduce this problem?
Hide
Constantin Ehrenstein added a comment -

(I hope this is rendered readably by JIRA)

phpunit.xml (in tests/):

<?xml version="1.0" encoding="utf-8"?>
<phpunit bootstrap="./application/bootstrap.php" colors="true">
	<testsuite name="skillerSite">
		<directory>./</directory>
	</testsuite>
	<filter>
		<whitelist>
			<directory suffix=".php">../application</directory>
			<exclude>
				<directory suffix=".phtml">../application</directory>
				<file>../application/Bootstrap.php</file>
				<file>../application/controllers/ErrorController.php</file>
			</exclude>
		</whitelist>
	</filter>
	<logging>
		<log type="coverage-html" target="./log/report" charset="utf-8"
			yui="true" highlight="true" lowUpperBound="50" highLowerBound="80" />
		<log type="textdox" target="./log/textdox.html" />
	</logging>
</phpunit>

in application.ini:

---8<--- snip ---8<---
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
phpSettings.date.default.timezone = "Europe/Vienna"
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.view[] =
---8<--- snip ---8<---

---8<--- snip ---8<---
[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.db.adapter = "Pdo_Sqlite"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/sitedata-testing.db"

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
;resources.db.adapter = "Pdo_Mysql"
;resources.db.params.host = "localhost"
---8<--- snip ---8<---

in tests/TechnologyMapperTest.php

<?php
class ModelTechnologyMapperTest extends ControllerTestCase {

	/**
	 * @var Default_Model_TechnologyMapper
	 */
	protected $_mapper;

	public function setUp() {
		$this->_mapper = new Default_Model_TechnologyMapper();
	}

	public function tearDown() {
		$this->_mapper->getDbTable()
			->delete(array("order_index = ?" => -101));
		$this->_mapper->getDbTable()
			->delete(array("order_index = ?" => -100));
	}

	public function testDbTableProperty() {
		$this->assertClassHasAttribute("_dbTable", "Default_Model_TechnologyMapper");
	}
---8<--- snip ---8<---

in application/models/TechnologyMapper.php:

<?php
class Default_Model_TechnologyMapper {
	/**
	 * The database table object
	 *
	 * @var Default_Model_DbTable_Technologies
	 */
	protected $_dbTable;

	/**
	 * Set the table object
	 * @param $dbTable
	 * @return Default_Model_TechnologyMapper
	 */
	public function setDbTable($dbTable) {
		if (is_string ( $dbTable )) {
			$dbTable = new $dbTable ( );
		}
		if (! $dbTable instanceof Zend_Db_Table_Abstract) {
			throw new Exception ( "Invalid table data gateway provider" );
		}
		$this->_dbTable = $dbTable;
		return $this;
	}

	/**
	 * Get the table object
	 * @return Default_Model_DbTable_Technologies
	 */
	public function getDbTable() {
		if (null === $this->_dbTable) {
			$this->setDbTable ( "Default_Model_DbTable_Technologies" );
		}
		return $this->_dbTable;
	}

	/**
	 * Save a technology
	 * @param Default_Model_Technology $tech
	 * @return Default_Model_TechnologyMapper
	 */
	public function save(Default_Model_Technology &$tech) {
		$data = array(
			"id"			=> $tech->getId(),
			"name"			=> $tech->getName(),
			"class_name"	=> $tech->getClassName(),
			"order_index"	=> $tech->getOrderIndex(),
		);
		if (null === $tech->getId()) {
			unset($data["id"]);
			$data["created"] = time();
			$tech->setId($this->getDbTable()->insert($data));
		}
		else {
			$data["modified"] = time();
			$this->getDbTable()->update($data, array("id = ?" => $data["id"]));
		}
		return $this;
	}

	public function fetchAll() {
		$resultSet = $this->getDbTable()
			->select()
			->order(array("order_index", "name"))
			->query()
			->fetchAll();
		$entries = array();
		foreach ($resultSet as $row) {
			$entry = new Default_Model_Technology();
			$entry->setId($row["id"])
				->setName($row["name"])
				->setClassName($row["class_name"])
				->setOrderIndex($row["order_index"]);
			$entries[] = $entry;
		}
		return $entries;
	}
}

in application/models/DbTable/Technologies.php:

<?php
class Default_Model_DbTable_Technologies extends Zend_Db_Table_Abstract {
	/**
	 * table name
	 * @var strings
	 */
	protected $_name = "technologies";
}
Show
Constantin Ehrenstein added a comment - (I hope this is rendered readably by JIRA) phpunit.xml (in tests/):
<?xml version="1.0" encoding="utf-8"?>
<phpunit bootstrap="./application/bootstrap.php" colors="true">
	<testsuite name="skillerSite">
		<directory>./</directory>
	</testsuite>
	<filter>
		<whitelist>
			<directory suffix=".php">../application</directory>
			<exclude>
				<directory suffix=".phtml">../application</directory>
				<file>../application/Bootstrap.php</file>
				<file>../application/controllers/ErrorController.php</file>
			</exclude>
		</whitelist>
	</filter>
	<logging>
		<log type="coverage-html" target="./log/report" charset="utf-8"
			yui="true" highlight="true" lowUpperBound="50" highLowerBound="80" />
		<log type="textdox" target="./log/textdox.html" />
	</logging>
</phpunit>
in application.ini:
---8<--- snip ---8<---
[production]
phpSettings.display_startup_errors = 0
phpSettings.display_errors = 0
phpSettings.date.default.timezone = "Europe/Vienna"
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.view[] =
---8<--- snip ---8<---

---8<--- snip ---8<---
[testing : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.db.adapter = "Pdo_Sqlite"
resources.db.params.dbname = APPLICATION_PATH "/../data/db/sitedata-testing.db"

[development : production]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
;resources.db.adapter = "Pdo_Mysql"
;resources.db.params.host = "localhost"
---8<--- snip ---8<---
in tests/TechnologyMapperTest.php
<?php
class ModelTechnologyMapperTest extends ControllerTestCase {

	/**
	 * @var Default_Model_TechnologyMapper
	 */
	protected $_mapper;

	public function setUp() {
		$this->_mapper = new Default_Model_TechnologyMapper();
	}

	public function tearDown() {
		$this->_mapper->getDbTable()
			->delete(array("order_index = ?" => -101));
		$this->_mapper->getDbTable()
			->delete(array("order_index = ?" => -100));
	}

	public function testDbTableProperty() {
		$this->assertClassHasAttribute("_dbTable", "Default_Model_TechnologyMapper");
	}
---8<--- snip ---8<---
in application/models/TechnologyMapper.php:
<?php
class Default_Model_TechnologyMapper {
	/**
	 * The database table object
	 *
	 * @var Default_Model_DbTable_Technologies
	 */
	protected $_dbTable;

	/**
	 * Set the table object
	 * @param $dbTable
	 * @return Default_Model_TechnologyMapper
	 */
	public function setDbTable($dbTable) {
		if (is_string ( $dbTable )) {
			$dbTable = new $dbTable ( );
		}
		if (! $dbTable instanceof Zend_Db_Table_Abstract) {
			throw new Exception ( "Invalid table data gateway provider" );
		}
		$this->_dbTable = $dbTable;
		return $this;
	}

	/**
	 * Get the table object
	 * @return Default_Model_DbTable_Technologies
	 */
	public function getDbTable() {
		if (null === $this->_dbTable) {
			$this->setDbTable ( "Default_Model_DbTable_Technologies" );
		}
		return $this->_dbTable;
	}

	/**
	 * Save a technology
	 * @param Default_Model_Technology $tech
	 * @return Default_Model_TechnologyMapper
	 */
	public function save(Default_Model_Technology &$tech) {
		$data = array(
			"id"			=> $tech->getId(),
			"name"			=> $tech->getName(),
			"class_name"	=> $tech->getClassName(),
			"order_index"	=> $tech->getOrderIndex(),
		);
		if (null === $tech->getId()) {
			unset($data["id"]);
			$data["created"] = time();
			$tech->setId($this->getDbTable()->insert($data));
		}
		else {
			$data["modified"] = time();
			$this->getDbTable()->update($data, array("id = ?" => $data["id"]));
		}
		return $this;
	}

	public function fetchAll() {
		$resultSet = $this->getDbTable()
			->select()
			->order(array("order_index", "name"))
			->query()
			->fetchAll();
		$entries = array();
		foreach ($resultSet as $row) {
			$entry = new Default_Model_Technology();
			$entry->setId($row["id"])
				->setName($row["name"])
				->setClassName($row["class_name"])
				->setOrderIndex($row["order_index"]);
			$entries[] = $entry;
		}
		return $entries;
	}
}
in application/models/DbTable/Technologies.php:
<?php
class Default_Model_DbTable_Technologies extends Zend_Db_Table_Abstract {
	/**
	 * table name
	 * @var strings
	 */
	protected $_name = "technologies";
}
Hide
Constantin Ehrenstein added a comment -

tests/application/ControllerTestCase.php:

<?php
class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {

	/**
	 * @var Zend_Application
	 */
	protected $_application;

	/**
	 * Prepares the environment before running a test.
	 */
	public function setUp() {
		$this->bootstrap = array($this, "appBootstrap" );
		parent::setUp();
	}

	public function appBootstrap() {
		$this->_application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . "/configs/application.ini" );
		$this->_application->bootstrap();
	}
}

Oh, and the tests/application/bootstrap.php file for unit testing:

<?php
error_reporting(E_ALL | E_STRICT);
date_default_timezone_set("Europe/Vienna");

defined("APPLICATION_PATH")
	|| define("APPLICATION_PATH", realpath(dirname(__FILE__) . "/../../application"));
defined("APPLICATION_ENV")
	|| define("APPLICATION_ENV", (getenv("APPLICATION_ENV") ? getenv("APPLICATION_ENV") : "testing"));
set_include_path(implode(PATH_SEPARATOR, array(
	get_include_path(),
	realpath(APPLICATION_PATH . "/../library"),
	"/usr/local/share/pear",
)));
require_once 'Zend/Loader/Autoloader.php';
require_once 'Zend/Application/Module/Autoloader.php';
/**
 * @var Zend_Application_Module_Autoloader
 */
$autoloader = new Zend_Application_Module_Autoloader(array(
	"namespace" => "Default",
	"basePath" => APPLICATION_PATH
));
require_once 'ControllerTestCase.php';
Show
Constantin Ehrenstein added a comment - tests/application/ControllerTestCase.php:
<?php
class ControllerTestCase extends Zend_Test_PHPUnit_ControllerTestCase {

	/**
	 * @var Zend_Application
	 */
	protected $_application;

	/**
	 * Prepares the environment before running a test.
	 */
	public function setUp() {
		$this->bootstrap = array($this, "appBootstrap" );
		parent::setUp();
	}

	public function appBootstrap() {
		$this->_application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . "/configs/application.ini" );
		$this->_application->bootstrap();
	}
}
Oh, and the tests/application/bootstrap.php file for unit testing:
<?php
error_reporting(E_ALL | E_STRICT);
date_default_timezone_set("Europe/Vienna");

defined("APPLICATION_PATH")
	|| define("APPLICATION_PATH", realpath(dirname(__FILE__) . "/../../application"));
defined("APPLICATION_ENV")
	|| define("APPLICATION_ENV", (getenv("APPLICATION_ENV") ? getenv("APPLICATION_ENV") : "testing"));
set_include_path(implode(PATH_SEPARATOR, array(
	get_include_path(),
	realpath(APPLICATION_PATH . "/../library"),
	"/usr/local/share/pear",
)));
require_once 'Zend/Loader/Autoloader.php';
require_once 'Zend/Application/Module/Autoloader.php';
/**
 * @var Zend_Application_Module_Autoloader
 */
$autoloader = new Zend_Application_Module_Autoloader(array(
	"namespace" => "Default",
	"basePath" => APPLICATION_PATH
));
require_once 'ControllerTestCase.php';
Hide
Ramon Henrique Ornelas added a comment -

@Constantin Ehrenstein

In class ModelTechnologyMapperTest (tests/TechnologyMapperTest.php).
Missing, parent::setUp().

<?php
class ModelTechnologyMapperTest extends ControllerTestCase
{

    /**
     * @var Default_Model_TechnologyMapper
     */
    protected $_mapper;

    public function setUp() {
        parent::setUp(); // add
        $this->_mapper = new Default_Model_TechnologyMapper();
    }

    public function tearDown() {
        $this->_mapper->getDbTable()
            ->delete(array("order_index = ?" => -101));
        $this->_mapper->getDbTable()
            ->delete(array("order_index = ?" => -100));
    }

    public function testDbTableProperty() {
        $this->assertClassHasAttribute("_dbTable", "Default_Model_TechnologyMapper");
    }
}
Show
Ramon Henrique Ornelas added a comment - @Constantin Ehrenstein In class ModelTechnologyMapperTest (tests/TechnologyMapperTest.php). Missing, parent::setUp().
<?php
class ModelTechnologyMapperTest extends ControllerTestCase
{

    /**
     * @var Default_Model_TechnologyMapper
     */
    protected $_mapper;

    public function setUp() {
        parent::setUp(); // add
        $this->_mapper = new Default_Model_TechnologyMapper();
    }

    public function tearDown() {
        $this->_mapper->getDbTable()
            ->delete(array("order_index = ?" => -101));
        $this->_mapper->getDbTable()
            ->delete(array("order_index = ?" => -100));
    }

    public function testDbTableProperty() {
        $this->assertClassHasAttribute("_dbTable", "Default_Model_TechnologyMapper");
    }
}

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: