TDD multiple databases

I am trying to test a model with a fixture. Nothing special, but in this case I am using two databases.

The DB’s are in both setup main.php and test.php config files. The first db is named ‘db’, the second ‘routedb’. The second DB has a ‘class’ => ‘CDbConnection’ (it’s working while non-testing).

The Model has a public function


public function getDbConnection() {

    return Yii::app()->routedb;

  }

so it should select the other db.

But while testing with fixtures, it says


CException: Table 'tbl_route' does not exist.

Of course, this table exists in ‘routedb’.

I work around this with commenting out the original ‘db’ and renaming ‘routedb’ to ‘db’, but that not the way I like it…

Is it possible to unittest with multiple databases? How do I do this?

Hi

I created a seperate bootstrap, for just this extra db and do


phpunit --bootstrap bs_routes.php unit\RouteTest.php

although not ideal, it is a lot better…

If anyone has a better solution, feel free.

Thanks for reading :wink:

Actually, I am having this very same issue. But the problem in my case is that I have a functional test and need to uses both databases in 1 test.

Is this possible? I am loading the fixtures through their model, but the fixturemanager doesn’t look as to which dbconnection should be used. I can created my own fixture manager, but I rather not. Any idea’s?

Fixed it. In setUp() function I added:




if(is_array($this->fixtures_alternate_db))

{

	$fixtureManager = new CDbFixtureManager();

	$fixtureManager->connectionID = 'db_alternate';

	$fixtureManager->load($this->fixtures_alternate_db);

}



Thanks Bobv!

I took your fix and expanded it a little to handle several databases. Also the configuration for the fixtures is all in the arrays and not in the setup method:

Example:




class SomeTest extends CDbTestCase

{

	// you can still use the regular fixture for 'db'

	public $fixtures=array(

		'reunion_queue'		=> 'ReunionQueue',

		'funky_music'		=> 'FunkyMusic',

	);


	public $extended_fixtures=array(

		'db2' => array(

				'email_backup'		=> 'EmailBackup',

			),

		'db3' => array(

				'ice_cream_recipes'	=> 'IceCreamRecipes',

			),

	);

	

	public function setUp()

	{

		parent::setUp();


		...


		foreach ($this->extended_fixtures as $connectionID => $fixtures)

		{

			$fixtureManager = new CDbFixtureManager();

			$fixtureManager->connectionID = $connectionID;

			$fixtureManager->load($fixtures);

		}

	}



Jeff’s solution worked for me, but I had to provide a basePath to the fixtureManager in the setUp method:


    public function setUp() {

        parent::setUp();

        

        foreach ($this->extended_fixtures as $connectionID => $fixtures) {

            $fixtureManager = new CDbFixtureManager();

            $fixtureManager->connectionID = $connectionID;

            $fixtureManager->basePath = Yii::app()->basePath.DIRECTORY_SEPARATOR.

                    'tests'.DIRECTORY_SEPARATOR.'fixtures';

            $fixtureManager->load($fixtures);

        }

    }

How do you get the fixture single record to use them in test case?

It is not possible to get the extended fixture like this: $this->ice_cream_recipes as usual - the alternative fixtureManager instance get lost in the setUp method.

how did you solve it? I think it needs to save the alternative fixture manager in a property. extending the class and override the magic get method.