Testes Unitários

Uma vez que o framework de testes do Yii é construído em cima do PHPUnit, é recomendado que você primeiro consulte sua documentação para entender o básico sobre como escrever um teste unitário. Nós resumimos a seguir os princípios básicos de escrita de um teste unitário no Yii:

A seguir, descrevemos principalmente como escrever testes unitários para classes de modelo active record. Estenderemos as nossas classes de CDbTestCase porque ela fornece o suporte às fixtures de banco de dados que introduzimos na seção anterior.

Suponha que queremos testar a classe do modelo Comment (comentário) no exemplo de blog. Começamos criando uma classe chamada de CommentTest e a salvando como protected/tests/unit/CommentTest.php:

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

Nesta classe, especificamos o atributo fixtures como um array que especifica quais fixtures serão usadas por este teste. O array representa um mapeamento dos nomes das fixtures aos nomes das classes de modelo ou aos nomes das tabelas das fixtures (por exemplo, do nome de fixture posts para a classe de modelo Post). Note que ao mapear para nomes de tabelas de fixtures, devemos prefixar o nome da tabela com dois pontos (por exemplo, :Post) para diferenciá-lo dos nomes de classe de modelo. E ao usar nomes de classes de modelo, as tabelas correspondentes serão consideradas como tabelas de fixtures. Conforme descrevemos anteriormente, as tabelas das fixtures serão resetadas a algum estado conhecido toda vez que um método de teste for executado.

Os nomes das fixtures nos permitem acessar os seus dados nos métodos de teste de uma maneira conveniente. O código a seguir demonstra a sua típica utilização:

// retorna todas as linhas na tabela da fixture 'Comment'
$comments = $this->comments;
// retorna a linha cujo alias é 'sample1' na tabela da fixture `Post`
$post = $this->posts['sample1'];
// retorna a instância de AR representando a linha de dados 'sample1'
$post = $this->posts('sample1');

Nota: Se uma fixture for declarada usando seu nome de tabela (por exemplo, 'posts'=>':Post'), então o terceiro uso acima não é válido porque nós não temos informações sobre com qual classe de modelo a tabela está associada.

Em seguida, escrevemos o método testApprove para testar o método approve na classe de modelo Comment. O código é bastante claro: primeiro inserimos um comentário de status pendente; então verificamos que este comentário está em status pendente retornando ele do banco de dados; e finalmente chamamos o método approve e verificamos se o status mudou conforme o esperado.

public function testApprove()
{
    // insere um comentário de status pendente
    $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));
 
    // verifica se o comentário está em status pendente
    $comment=Comment::model()->findByPk($comment->id);
    $this->assertTrue($comment instanceof Comment);
    $this->assertEquals(Comment::STATUS_PENDING,$comment->status);
 
    // chama approve() e verifica se o comentário tem o status aprovado
    $comment->approve();
    $this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
    $comment=Comment::model()->findByPk($comment->id);
    $this->assertEquals(Comment::STATUS_APPROVED,$comment->status);
}
$Id$