How to create model object in Yii PHPUnit test without fixture?

I am writing a PHPUnit test for my Yii application. I read here :

Tip. Too many instrument files can increase test time dramatically. For this reason, you should only provide attachment files for tables whose contents may change during the test. Tables that serve to ensure that the distortion does not change and therefore does not need binding files.

I really have a large fixture (180 entries, which require loading> 20 seconds), which is used only as a view. However, I need to easily convert it from an associative array to a model object, as is usually the case with instrument syntax. The Council suggests that there is also a way to create a model object without using a device, but it is not mentioned how this is done. Can anyone help?

Creating a model object with a mount:

// tests/fixtures/Order.php return array( 'row_id' => array( 'id' => 1, 'name' => 'hello', ) ) // tests/unit/AbcTest.php public $fixtures = array( 'orders' => 'Order', ) public test_abc() { $order = $this->orders('row_id'); .... } 
+5
source share
2 answers

Another option: When you create db migration , you should apply it to production db and test db, in addition, you should fill the test tables with test data.

The advantages of this approach:

  • You run sql sql only once (not like fixture - it calls a test every time).
  • Your test will run quickly because db will be prepared.
  • When you make a new function that needs a new test with new data in db, you create a db migration and it will be executed only once, in an explicit way.

For instance:

 <?php class m150608_110143_init extends CDbMigration { public function safeUp() { $sql1 = " CREATE TABLE brand ( id INT AUTO_INCREMENT, name VARCHAR(100) NOT NULL DEFAULT '', country VARCHAR(50) NOT NULL DEFAULT '', PRIMARY KEY (id) ); "; $sql2 = " INSERT INTO brand VALUES (null, 'aston martin', 'UK'), (null, 'audi', 'Germany'), (null, 'bmw', 'Germany'), (null, 'citroen', 'France'), (null, 'peugeot', 'France'), (null, 'porsche', 'Germany'), (null, 'toyota', 'Japan'), (null, 'ferrari', 'Italy') ; "; // Production db. $this->setDbConnection(Yii::app()->db); $this->execute($sql1); // Test db. $this->setDbConnection(Yii::app()->dbUnitTest); $this->execute($sql1); // Populate test db with fixtures. $this->execute($sql2); return true; } public function down() { $sql = 'DROP TABLE brand;'; // Test db. $this->setDbConnection(Yii::app()->dbUnitTest); $this->execute($sql); // Production db. $this->setDbConnection(Yii::app()->db); $this->execute($sql); return true; } } 

And in the test, you do not need to think about lights.

+3
source

Yes, it is possible to achieve the desired.
For example: I have a brand model that has its own device:

 <?php // protected/tests/fixtures/brand.php return [ 1 => [ 'name' => 'Lexus', 'country' => 'JPN', ], 2 => [ 'name' => 'Acura', 'country' => 'JPNE', ], ]; 

and I have the following code:

  $brand = new Brand; $allBrands = $brand->findAll(); 

This code will return an array with 2 CActiveRecord objects. And all we need is it just creates the same array with two CActiveRecord objects:

 public function testGetAllAvailableBrands() { // Get brands from fixture. $brand = new Brand; $allBrandsFromFixture = $brand->findAll(); // Generate brands. $lexus = new Brand; $lexus->scenario = 'update'; $lexus->name = 'Lexus'; $lexus->country = 'JPN'; $lexus->id = 1; $lexus->setPrimaryKey(1); $lexus->setIsNewRecord(false); $allBrandsGeneratedAtRuntime[] = $lexus; $acura = new Brand; $acura->scenario = 'update'; $acura->name = 'Acura'; $acura->country = 'JPNE'; $acura->id = 2; $acura->setPrimaryKey(2); $acura->setIsNewRecord(false); $allBrandsGeneratedAtRuntime[] = $acura; // Brands from fixture should be equals to generated brands. $this->assertEquals($allBrandsFromFixture, $allBrandsGeneratedAtRuntime); } 

This test will be green because our brands are exactly the same. You cat, try something like this.

But I think that the yii built-in tools look much better, and in order not to increase the testing time, you should use the .init.php files ...

+1
source

All Articles