Commit 12ff8630 by Qiang Xue

refactored fixture implementation.

parent 106e9124
......@@ -118,7 +118,7 @@ use app\tests\fixtures\UserProfileFixture;
class UserProfileTest extends TestCase
{
public function fixtures()
protected function fixtures()
{
return [
'profiles' => UserProfileFixture::className(),
......
......@@ -49,45 +49,6 @@ class TestCase extends Test
}
/**
* Returns the value of an object property.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when executing `$value = $object->property;`.
* @param string $name the property name
* @return mixed the property value
* @throws UnknownPropertyException if the property is not defined
*/
public function __get($name)
{
$fixture = $this->getFixture($name);
if ($fixture !== null) {
return $fixture;
} else {
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
}
/**
* Calls the named method which is not a class method.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when an unknown method is being invoked.
* @param string $name the method name
* @param array $params method parameters
* @throws UnknownMethodException when calling unknown method
* @return mixed the method return value
*/
public function __call($name, $params)
{
$fixture = $this->getFixture($name);
if ($fixture instanceof ActiveFixture) {
return $fixture->getModel(reset($params));
} else {
throw new UnknownMethodException('Unknown method: ' . get_class($this) . "::$name()");
}
}
/**
* Mocks up the application instance.
* @param array $config the configuration that should be used to generate the application instance.
* If null, [[appConfig]] will be used.
......
......@@ -9,16 +9,75 @@ namespace yii\test;
use Yii;
use yii\base\InvalidConfigException;
use yii\base\UnknownMethodException;
use yii\base\UnknownPropertyException;
/**
* FixtureTrait provides functionalities for loading, unloading and accessing fixtures for a test case.
*
* By using FixtureTrait, a test class will be able to specify which fixtures to load by overriding
* the [[fixtures()]] method. It can then load and unload the fixtures using [[loadFixtures()]] and [[unloadFixtures()]].
* Once a fixture is loaded, it can be accessed like an object property, thanks to the PHP `__get()` magic method.
* Also, if the fixture is an instance of [[ActiveFixture]], you will be able to access AR models
* through the syntax `$this->fixtureName('model name')`.
*
* @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0
*/
trait FixtureTrait
{
/**
* @var array the list of fixture objects available for the current test.
* The array keys are the corresponding fixture class names.
* The fixtures are listed in their dependency order. That is, fixture A is listed before B
* if B depends on A.
*/
private $_fixtures;
/**
* @var array the fixture class names indexed by the corresponding fixture names (aliases).
*/
private $_fixtureAliases;
/**
* Returns the value of an object property.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when executing `$value = $object->property;`.
* @param string $name the property name
* @return mixed the property value
* @throws UnknownPropertyException if the property is not defined
*/
public function __get($name)
{
$fixture = $this->getFixture($name);
if ($fixture !== null) {
return $fixture;
} else {
throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);
}
}
/**
* Calls the named method which is not a class method.
*
* Do not call this method directly as it is a PHP magic method that
* will be implicitly called when an unknown method is being invoked.
* @param string $name the method name
* @param array $params method parameters
* @throws UnknownMethodException when calling unknown method
* @return mixed the method return value
*/
public function __call($name, $params)
{
$fixture = $this->getFixture($name);
if ($fixture instanceof ActiveFixture) {
return $fixture->getModel(reset($params));
} else {
throw new UnknownMethodException('Unknown method: ' . get_class($this) . "::$name()");
}
}
/**
* Declares the fixtures that are needed by the current test case.
* The return value of this method must be an array of fixture configurations. For example,
*
......@@ -38,31 +97,19 @@ trait FixtureTrait
*
* @return array the fixtures needed by the current test case
*/
public function fixtures()
protected function fixtures()
{
return [];
}
/**
* @var array the list of fixture objects available for the current test.
* The array keys are the corresponding fixture class names.
* The fixtures are listed in their dependency order. That is, fixture A is listed before B
* if B depends on A.
*/
private $_fixtures;
/**
* @var array the fixture class names indexed by the corresponding fixture names (aliases).
*/
private $_fixtureAliases;
/**
* Loads the fixtures.
* This method will load the fixtures specified by `$fixtures` or [[fixtures()]].
* @param array $fixtures the fixtures to loaded. If not set, [[fixtures()]] will be loaded instead.
* @throws InvalidConfigException if fixtures are not properly configured or if a circular dependency among
* the fixtures is detected.
*/
public function loadFixtures($fixtures = null)
protected function loadFixtures($fixtures = null)
{
if ($fixtures === null) {
$fixtures = $this->fixtures();
......@@ -120,7 +167,7 @@ trait FixtureTrait
/**
* Unloads all existing fixtures.
*/
public function unloadFixtures()
protected function unloadFixtures()
{
/** @var Fixture $fixture */
foreach (array_reverse($this->_fixtures) as $fixture) {
......@@ -131,7 +178,7 @@ trait FixtureTrait
/**
* @return array the loaded fixtures for the current test case
*/
public function getFixtures()
protected function getFixtures()
{
return $this->_fixtures;
}
......@@ -141,7 +188,7 @@ trait FixtureTrait
* @param string $name the fixture alias or class name
* @return Fixture the fixture object, or null if the named fixture does not exist.
*/
public function getFixture($name)
protected function getFixture($name)
{
$class = isset($this->_fixtureAliases[$name]) ? $this->_fixtureAliases[$name] : $name;
return isset($this->_fixtures[$class]) ? $this->_fixtures[$class] : null;
......
......@@ -21,7 +21,17 @@ class MyDbTestCase
{
use FixtureTrait;
public function fixtures()
public function setUp()
{
$this->loadFixtures();
}
public function tearDown()
{
$this->unloadFixtures();
}
protected function fixtures()
{
return [
'customers' => CustomerFixture::className(),
......@@ -51,8 +61,8 @@ class ActiveFixtureTest extends DatabaseTestCase
public function testGetRows()
{
$test = new MyDbTestCase();
$test->loadFixtures();
$fixture = $test->getFixture('customers');
$test->setUp();
$fixture = $test->customers;
$this->assertEquals(CustomerFixture::className(), get_class($fixture));
$this->assertEquals(2, count($fixture));
$this->assertEquals(1, $fixture['customer1']['id']);
......@@ -64,8 +74,8 @@ class ActiveFixtureTest extends DatabaseTestCase
public function testGetModel()
{
$test = new MyDbTestCase();
$test->loadFixtures();
$fixture = $test->getFixture('customers');
$test->setUp();
$fixture = $test->customers;
$this->assertEquals(Customer::className(), get_class($fixture->getModel('customer1')));
$this->assertEquals(1, $fixture->getModel('customer1')->id);
$this->assertEquals('customer1@example.com', $fixture->getModel('customer1')->email);
......
......@@ -63,7 +63,22 @@ class MyTestCase
public static $load;
public static $unload;
public function fixtures()
public function setUp()
{
$this->loadFixtures();
}
public function tearDown()
{
$this->unloadFixtures();
}
public function fetchFixture($name)
{
return $this->getFixture($name);
}
protected function fixtures()
{
switch ($this->scenario) {
case 0: return [];
......@@ -105,9 +120,9 @@ class FixtureTest extends TestCase
foreach ($this->getDependencyTests() as $scenario => $result) {
$test = new MyTestCase();
$test->scenario = $scenario;
$test->loadFixtures();
$test->setUp();
foreach ($result as $name => $loaded) {
$this->assertEquals($loaded, $test->getFixture($name) !== null, "Verifying scenario $scenario fixture $name");
$this->assertEquals($loaded, $test->fetchFixture($name) !== null, "Verifying scenario $scenario fixture $name");
}
}
}
......@@ -119,9 +134,9 @@ class FixtureTest extends TestCase
$test->scenario = $scenario;
MyTestCase::$load = '';
MyTestCase::$unload = '';
$test->loadFixtures();
$test->setUp();
$this->assertEquals($result[0], MyTestCase::$load, "Verifying scenario $scenario load sequence");
$test->unloadFixtures();
$test->tearDown();
$this->assertEquals($result[1], MyTestCase::$unload, "Verifying scenario $scenario unload sequence");
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment