Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a Model object in Yii PHPUnit test without a fixture?

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

Tip: Having too many fixture files could increase the test time dramatically. For this reason, you should only provide fixture files for those tables whose content may change during the test. Tables that serve as look-ups do not change and thus do not need fixture files.

I indeed have a large fixture (180 records, which takes >20 seconds to load), which is only used as a look-up. However, I do need to transform it easily from an associative array into a Model object, like you can usually do with the fixture syntax below. The tip suggests that there is also a way to create a Model object without the use of a fixture, but does not mention how this is done. Can anyone help out?

Creation of Model object with a fixture:

// 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');
    ....
}
like image 458
physicalattraction Avatar asked Sep 27 '22 12:09

physicalattraction


1 Answers

Yes, it's possible to reach what you wish.
For example: i have model brand that have own fixture:

<?php
// protected/tests/fixtures/brand.php

return [
    1 => [
        'name' => 'Lexus',
        'country' => 'JPN',
    ],
    2 => [
        'name' => 'Acura',
        'country' => 'JPNE',
    ],
];

and i have next code:

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

This code will return array with 2 CActiveRecord objects. And everything what we need - it's just build the same array with 2 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 exactly the same. You cat try something like this.

But i think that native yii fixtures looks much better, and to avoid increase the test time you should use .init.php files...

like image 151
cn007b Avatar answered Oct 12 '22 18:10

cn007b