Enhetstestning

Eftersom Yii:s testningsramverk använder sig av PHPUnit, rekommenderas PHPUnit-dokumentationen för att ge en grundläggande förståelse för hur man skriver ett enhetstest. Vi sammanfattar följande grundläggande principer för hur man skriver ett enhetstest i Yii:

I det följande beskrivs i huvudsak hur man skriver enhetstester för Active Record modellklasser. Vi kommer att ärva våra testklasser från CDbTestCase eftersom denna erbjuder stöd för databasfixturer (som introducerades i föregående avsnitt).

Antag att vi vill testa modellklassen Comment i applikationen blog demo. Vi börjar med att skapa en klass och ger den namnet CommentTest samt sparar den som protected/tests/unit/CommentTest.php:

class CommentTest extends CDbTestCase
{
    public $fixtures=array(
        'posts'=>'Post',
        'comments'=>'Comment',
    );
 
    ......
}

I denna klass specificerar vi medlemsvariabeln fixtures till att vara en array som specificerar vilka fixturer som kommer användas av detta test. Arrayen representerar en mappning mellan fixturnamn och modellklassnamn alternativt fixturtabellnamn (t.ex. från fixturnamnet posts till modellklassen Post). Märk att när mappningen sker till fixturtabellnamn sätter vi in ett kolon som prefix före tabellnamnet (t.ex. :Post) för att särskilja det från modellklassnamn. Vid användning av modelklassnamn kommer motsvarande tabeller att betraktas som fixturtabeller. Som tidigare beskrivits återställs fixturtabeller till något känt tillstånd varje gång en testmetod exekveras.

Fixturnamn ger tillgång till fixturdata från testmetoder på ett praktiskt sätt. Följande kod ger typiska användningsexempel:

// return all rows in the 'Comment' fixture table
$comments = $this->comments;
// return the row whose alias is 'sample1' in the `Post` fixture table
$post = $this->posts['sample1'];
// return the AR instance representing the 'sample1' fixture data row
$post = $this->posts('sample1');

Märk: Om en fixtur har deklarerats med sitt tabellnamn (t.ex. 'posts'=>':Post'), är det tredje exemplet ovan inte giltigt eftersom vi inte har någon information om
vilken modellklass tabellen är associerad till.

Nu skriver vi en metod testApprove för att testa metoden approve i modellklassen Comment. Koden är okomplicerad: först sätter vi in en kommentar som åsätts status Pending; därefter verifierar vi, genom att hämta tillbaka kommentaren från databasen, att den erhållit status Pending; slutligen anropar vi metoden approve och verifierar att status ändras som förväntat.

public function testApprove()
{
    // insert a comment in pending status
    $comment=new Comment;
    $comment->setAttributes(array(
        'content'=>'comment 1',
        'status'=>Comment::STATUS_PENDING,
        'createTime'=>time(),
        'author'=>'me',
        'email'=>'me@example.com',
        'postId'=>$this->posts['sample1']['id'],
    ),false);
    $this->assertTrue($comment->save(false));
 
    // verify the comment is in pending status
    $comment=Comment::model()->findByPk($comment->id);
    $this->assertTrue($comment instanceof Comment);
    $this->assertEquals(Comment::STATUS_PENDING,$comment->status);
 
    // call approve() and verify the comment is in approved status
    $comment->approve();
    $this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
    $comment=Comment::model()->findByPk($comment->id);
    $this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
}
$Id: test.unit.txt 2841 2011-01-12 21:04:12Z alexander.makarow $