Yii Framework Forum: TDD, Fixtures with 1.1.5 - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

TDD, Fixtures with 1.1.5 Rate Topic: -----

#1 User is offline   imehesz 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 717
  • Joined: 13-June 09
  • Location:Jacksonville, FL

Posted 25 December 2010 - 12:05 PM

hello everybody,

Merry Christmaaaaas ...

So I have the following setup:

prefix: tbl_

table name: tbl_jobs

my protected/tests/fixtures/tbl_jobs.php fixture:

<?php
	return array(
		'job1'	=> array(
			'id'			=> 1,
			'company'		=> 'Facebook',
		),
		'job2'	=> array(
			'id'			=> 2,
			'company'		=> 'Google',
		),

	);


my protected/tests/unit/JobTest.php test case:

<?php
	class JobTest extends CTestCase
	{
		public $fixtures = array( 'jobs' => 'Job' );

		public function testCount()
		{
                        // i'm expecting 2 here -> see fixture file
			$this->assertEquals( 2,sizeof( $this->jobs  ) );	
		}
	}


and my unit-test output looks like this:

1) JobTest::testCount
Undefined property: JobTest::$jobs

/var/www/p/Project-J/protected/tests/unit/JobTest.php:10


it seems like it's not loading my fixtures (undefined property)

What am I missing?

I have more fields in the table, but I think that should be ok ///

thx,
--iM
It’s done, the great act of creation.
The maker rests. The wheel’s in motion.
-- Imre Madách

check out Yii2 Theme Factory at http://yii2.themefactory.net
0

#2 User is offline   imehesz 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 717
  • Joined: 13-June 09
  • Location:Jacksonville, FL

Posted 25 December 2010 - 12:34 PM

I FOUND IT :)

so I originally created my model with the Gii tool, which didn't add the fixtures and tests for me :/

after a little google-ing I re-run my model creation with the yiic tool and voi'la, everything works :D gotta love it!

the only difference that I can see was, that I extended my JobTest from CTestCase and not from CDbTestCase. Of course, now it makes sense ...

so back on track ..

--iM
It’s done, the great act of creation.
The maker rests. The wheel’s in motion.
-- Imre Madách

check out Yii2 Theme Factory at http://yii2.themefactory.net
1

#3 User is offline   Nickerson 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 3
  • Joined: 15-January 11

Posted 23 January 2011 - 11:42 AM

I was having similar problems, however my solution was a bit different.

My fixtures reference looked like:


public $fixtures = array(
		'users' => 'User'
	);


But I was getting the error:
Exception: Unknown property 'users' for class 'UserTest'.


My fixture file was set to 'User.php', which was the problem. You have to name the file the same as the DB table with the included prefix if you're using one.

The solution was to rename the file from 'User.php' to 'tp_user.php' where 'tp_' is my table prefix for the Test DB connection.
0

#4 User is offline   Jethro Lee 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 24-November 11

Posted 24 November 2011 - 10:29 PM

View PostNickerson, on 23 January 2011 - 11:42 AM, said:

You have to name the file the same as the DB table with the included prefix if you're using one.


Thanks to @Nickerson for this really helps, save me a lot of time. :)

In my case, I don't use table prefix. The tip is that one has to make fixture file name, fixture table name and the table name in database exactly the same; for example,

	// in protected/test/unit/foobarTest.php
	public $fixtures = array(
		"user" => ":user", 
	);
	


The following must reside in the fixture file named as "user.php" ("User.php" does not work).

	// in protected/test/fixtures/user.php
	return array(
	"user1" => array(
		"username" => "agent.smith@example.com", 
		"fullname" => "Agent Smith", 
	),	
	

0

#5 User is offline   Neoc83 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 05-February 14

Posted 13 February 2014 - 04:08 AM

I want to share my experiences regarding fixtures and table prefixes as I think it might be helpful for others.

For the Post model I have a table named 'tbl_post' and the prefix configured as 'tbl_'. To make it work with fixtures I defined the following fixture in my test file:

protected $fixtures = array(
    '{{post}}' => 'Post',
);


As mentioned in previous posts, the fixture file needs to be named to the full table name: 'tbl_post.php'. The file looks like this:

return array(
    'sample1' => array(
        'title' => 'post1',
        'text' => 'post1',
    ),
    'sample2' => array(
        'title' => 'post2',
        'text' => 'post2',
    ),
);


This all worked well but then I wanted to refer to the fixture data in the test cases. Normally you would be able to use the following code to refer to the fixture AR instance with alias 'sample1':

$this->post('sample1');


However, this doesn't work when using a prefix and '{{post}}' as the fixure name. In order to resolve this I wrote a class DbTestCase that extends CDbTestCase and overrides the PHP magic methods __get and __call. This is the result:

/**
 * Class extends from CDbTestCase to include support for fixture data getters 
 * with prefixed table names.
 */
class DbTestCase extends CDbTestCase {

    /**
     * Sets up before each test method runs.
     */
    protected function setUp() {
        parent::setUp();
    }

    /**
     * PHP magic method.
     * This method is overridden so that named fixture data can be accessed like 
     * a normal property even when a table prefix is used.
     * @param string $name the property name
     * @throws Exception if unknown property is used
     * @return mixed the property value
     */
    public function __get($name) {

        if (is_array($this->fixtures) && ($rows = $this->getFixtureManager()->getRows($name)) !== false) {
            return $rows;
        } else if (Yii::app()->db->tablePrefix !== null) {
            $name = '{{' . $name . '}}';
            if (is_array($this->fixtures) && ($rows = $this->getFixtureManager()->getRows($name)) !== false) {
                return $rows;
            }
        } else {
            throw new Exception("Unknown property '$name' for class '" . get_class($this) . "'.");
        }
    }

    /**
     * PHP magic method.
     * This method is overridden so that named fixture ActiveRecord instances 
     * can be accessed in terms of a method call even when a table prefix is used.
     * @param string $name method name
     * @param string $params method parameters
     * @throws Exception if unknown method is used
     * @return mixed the property value
     */
    public function __call($name, $params) {
        if (is_array($this->fixtures) && isset($params[0]) && ($record = $this->getFixtureManager()->getRecord($name, $params[0])) !== false) {
            return $record;
        } else if (Yii::app()->db->tablePrefix !== null) {
            $name = '{{' . $name . '}}';
            if (is_array($this->fixtures) && isset($params[0]) && ($record = $this->getFixtureManager()->getRecord($name, $params[0])) !== false) {
                return $record;
            }
        } else {
            throw new Exception("Unknown method '$name' for class '" . get_class($this) . "'.");
        }
    }

}


Extending my test case classes from this new class DbTestCase, I was able to refer to fixture data:


class PostTest extends DbTestCase {

    protected $fixtures = array(
        '{{post}}' => 'Post',
    );

    function testDelete() {
        $post = $this->post('sample1');
        $post->delete();
        $this->assertNull(Post::model()->findByPk($post->id));
    }

}



I hope this can be helpful for anyone that is using prefixes and fixtures. The only thing I'm still looking at is making the fixture file name independent from the prefix. Maybe someone has a good suggestion?
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users