<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Léo Hackin 0.2c &#187; mockobjects</title>
	<atom:link href="http://www.leohackin.com.br/tag/mockobjects/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.leohackin.com.br</link>
	<description>Eternamente beta, geralmente funcional</description>
	<lastBuildDate>Wed, 21 Jul 2010 00:34:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Mock Objects no SimpleTest</title>
		<link>http://www.leohackin.com.br/2009/12/mock-objects-no-simpletest/</link>
		<comments>http://www.leohackin.com.br/2009/12/mock-objects-no-simpletest/#comments</comments>
		<pubDate>Fri, 04 Dec 2009 15:51:34 +0000</pubDate>
		<dc:creator>Léo Hackin</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[mockobjects]]></category>
		<category><![CDATA[simpletest]]></category>

		<guid isPermaLink="false">http://www.leohackin.com.br/?p=253</guid>
		<description><![CDATA[Olá pessoal, Continuando nossa sequência de artigos sobre o SimpleTest, já aprendemos como fazer testes unitários e agrupa-los para facilitar a execução em lote: agora vamos falar um pouco sobre mock objects. Até agora, nossos testes unitários se resumiram a testar métodos e funcionalidades que envolviam apenas uma classe como nossa calculadora: tínhamos um método chamado [...]]]></description>
			<content:encoded><![CDATA[
<div class="topsy_widget_data topsy_theme_jade" style="float: right;margin-left: 0.75em;"><script type="text/javascript" src="http://button.topsy.com/widget/retweet-small?url=http://www.leohackin.com.br/2009/12/mock-objects-no-simpletest/&amp;title=Mock+Objects+no+SimpleTest&amp;theme=jade&amp;order=count,retweet,badge&amp;txt_tweet=tuit&amp;txt_retweet=retuit"></script></div><p>Olá pessoal,</p>
<p>Continuando nossa sequência de artigos sobre o <a href="http://www.simpletest.org" target="_blank">SimpleTest</a>, já aprendemos <a href="http://www.leohackin.com.br/2009/07/iniciando-com-o-simpletest/" target="_blank">como fazer testes unitários</a> e <a href="http://www.leohackin.com.br/2009/07/agrupando-casos-de-teste-no-simpletest/" target="_blank">agrupa-los</a> para facilitar a execução em lote: agora vamos falar um pouco sobre <strong>mock objects</strong>.</p>
<p>Até agora, nossos testes unitários se resumiram a <strong>testar métodos e funcionalidades que envolviam apenas uma classe</strong> como nossa calculadora: tínhamos um método chamado &#8220;somar&#8221; que fazia parte da própria classe e recebia como parametro de entrada apenas dois inteiros.</p>
<p>A idéia do <strong>teste unitário</strong> (ou de unidade), como o próprio nome diz, é <strong>isolar e testar apenas aquele ponto e funcionalidade</strong> do software: então é imprescindível que possamos isolar da melhor maneira apenas a classe/métodos que desejamos testar para que, caso apresente falha, possamos <strong>identificar exatamente onde a falha ocorreu</strong>.</p>
<p>Mas e quando nossa classe depende de outra(s) classe(s) para fazer um método funcionar ?</p>
<p><span id="more-253"></span></p>
<h2><span style="font-weight: normal;">Conceituando o problema</span></h2>
<p>Então, vamos imaginar a seguinte situação: estamos desenvolvendo um software de e-commerce e em dado momento precisamos validar se um usuário existe em nosso banco de dados. Apesar das possibilidades abrangentes de um sistema de validação/autenticação, vamos nos preocupar com o básico e implementá-lo de uma forma simples como abaixo:</p>
<div id="attachment_264" class="wp-caption aligncenter" style="width: 568px"><img class="size-full wp-image-264" title="As classes usadas no validador" src="http://www.leohackin.com.br/wp-content/uploads/2009/12/diagrama_validator.gif" alt="As classes usadas no validador" width="558" height="181" /><p class="wp-caption-text">As classes usadas no validador</p></div>
<p>Vamos criar uma classe chamada <em><span style="text-decoration: underline;">Validator</span></em>, que receberá o login do usuário, verificará no banco de dados se ele existe ou não e validará seu acesso. Para tanto, nossa classe de validação terá um método chamado <em>validate</em>, que receberá um parâmetro <em>string</em> representando o nome do usuário a ser validado.</p>
<p>Para conectar-se ao banco de dados, nossa classe receberá em sua criação um objeto referente à classe <em><span style="text-decoration: underline;">Conexao</span></em>, que disponibilizará um método chamado <em><span style="text-decoration: underline;">query</span></em>, que consulta o banco e retorna uma array de resultados.</p>
<p><strong><span style="color: #000080;">classe validator.php</span></strong></p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Validator <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$conexao</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">conexao</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conexao</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> validate<span style="color: #009900;">&#40;</span><span style="color: #000088;">$nome</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #666666; font-style: italic;">// aqui vai a lógica para verificar se o usuário existe ou não e que vamos testar</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p><span style="color: #000080;"><strong><span style="color: #333399;">classe conexao.php</span></strong></span></p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Conexao <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #666666; font-style: italic;">// configura o acesso ao banco de dados</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> query<span style="color: #009900;">&#40;</span><span style="color: #000088;">$query</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #666666; font-style: italic;">// retorna um array com os resultados da consulta</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Para que tudo fique mais claro, podemos dar uma olhada em como ficaria nosso código final da aplicação:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Config<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #000088;">$Conexao</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$validator</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Validator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$usuario</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">'Léo'</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$validator</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$usuario</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #666666; font-style: italic;">// redireciona para a página restrita</span><br />
<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #666666; font-style: italic;">// retorna uma alerta falando que o usuário não existe</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Como aprendemos em nosso primeiro artigo sobre TDD, <strong>primeiro fazemos os testes e depois fazemos nossa aplicação passar nos neles</strong>, implementando a lógica de negócio válida. Nosso objetivo nesse momento é <strong>testar o método validate</strong>: fazendo um pouco de nossa flexão mental chegamos a dois comportamentos válidos para o método:</p>
<ul>
<li>Se o usuário existir, ele retornará true;</li>
<li>Se o usuário não existir, ele retornará false;</li>
</ul>
<h2><span style="font-weight: normal;">O problema </span></h2>
<p>Então, pensamos &#8220;<em>Bacana! Então vou fazer um caso de teste chamado ValidatorTestCase e um teste chamado testValidarSeUsuarioExistir que irá validar se um usuário foi validado se ele existir!</em>&#8220;.</p>
<p>Partimos para o código então:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> ValidatorTestCase <span style="color: #000000; font-weight: bold;">extends</span> UnitTestCase <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> testValidarSeUsuarioExistir<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000088;">$config</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Config<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Conexao<span style="color: #009900;">&#40;</span><span style="color: #000088;">$config</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$validator</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Validator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEqual</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$validator</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p><strong>Tudo ok ?</strong> <span style="color: #800000;"><strong><span style="color: #ff0000;">NADA OK!</span></strong></span> O código acima pode funcionar mas temos alguns problemas:</p>
<ul>
<li>Como garantir que nosso banco de dados vai estar disponível na hora do teste ?</li>
<li>Como vamos saber se existe o usuário que queremos testar está no banco, para testarmos se a validação realmente vai passar no teste e se comportar como queremos ?</li>
<li>E se ocorrer um erro de conexão ao banco no meio do teste ?</li>
<li>E se a conexão banco for demorada e nosso caso de teste ter 50 testes acessando o banco? oO</li>
<li>Como saber se as configurações estão exatas para a conexão no banco? Aliás, eu nem sei nada sobre config até agora!</li>
<li>E principalmente: e se ocorrer um problema na pesquisa da query que não tenha nada haver exatamente com nosso validador, já que nosso objetivo é testar unicamente se &#8220;ao receber um usuário, verificar se ele existe no banco e validar em caso afirmativo&#8221;.</li>
</ul>
<p><strong>Haja coisa né ?</strong></p>
<h2><span style="font-weight: normal;">Mock Objects (nosso boneco de testes)</span></h2>
<p>Pensando nesse problema, foram criados os <strong>Mock objects</strong>. Um mock object (vou usar o termo em inglês pois a esmagadora maioria das referências TDD estão assim) nada mais é que <strong>um objeto que simula e imita o comportamento de um objeto real</strong>.</p>
<p>Imagine os <strong>bonecos de teste de batidas de carro</strong>: os engenheiros os constroem com peso, altura, juntas e vários aspectos que <strong>imitam o corpo de um ser humano para poderem fazer seus testes</strong>. Eles colocam esses bonecos nas mais variadas situações e posições possíveis para testarem a segurança de um carro entre outras coisas, sem precisar matar ninguém para isso. <img src='http://www.leohackin.com.br/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> </p>
<p>No nosso caso, nossos <strong>mock objects são representações de classes reais onde podemos simular e forçar qualquer comportamento que desejamos para testarmos certas situações</strong> que talvez não seriam possíveis de serem alcançadas &#8220;explicitamente&#8221; sem gambiarra-las ou mesmo que sejam de dificil configuração.</p>
<p>Em resumo, usamos um mock quando nossa classe real (<span style="color: #c0c0c0;">colado do wikipedia &#8211; thank&#8217;s god</span>):</p>
<ul>
<li>gera resultados não deterministicos (e.g. a hora ou temperatura atual);</li>
<li>tem estados que são difíceis de criar ou reproduzir (e.g. erro de comunicação da rede);</li>
<li>é lento (e.g. um banco de dados completo que precisa ser inicializado antes do teste);</li>
<li>ainda não existe ou pode ter comportamento alterado;</li>
<li>teriam que adicionar informações e métodos exclusivamente para os testes (e não para sua função real).</li>
</ul>
<p>Analisando nosso problema anterior, podemos constatar que nossa classe <em><span style="text-decoration: underline;">Conexao</span></em> é forte candidata à ser &#8220;mockeada&#8221;: assim nos livramos de todos aqueles problemas de conexão, de existência de registros e tudo mais que não tem nada haver com nosso teste unitário em si, que diz respeito pura e diretamente à nossa classe <em><span style="text-decoration: underline;">Validator</span></em>.</p>
<p>Ou seja, <strong>ao invés de usar a classe Conexao real, vamos usar uma &#8220;imitação&#8221; dela, muito mais simples e fácil de manipular</strong> para chegarmos de forma mais simples ao nosso resultado esperado no teste unitário. Vamos utilizar esse mock pois não faz sentido testar a conexão nem nenhum método dessa classe e sim utilizar o comportamento referente ao código que vamos utilizar no nosso teste.</p>
<h2><span style="font-weight: normal;">Codando!</span></h2>
<p>Como vimos, nossa classe <em><span style="text-decoration: underline;">Conexao</span></em> não tem nada implementado ainda. Mas isso não nos interessa pois vamos fazer um mock da classe, para podermos simular o que precisamos: o retorno dos resultados que desejamos para testar o método <em><span style="text-decoration: underline;">validate</span></em> do <em><span style="text-decoration: underline;">Validator</span></em>.</p>
<p><strong>Para criar um mock de nossa classe</strong>, simplesmente fazemos o include dessa classe em nosso teste e &#8220;geramos&#8221; esse mock com o método <em><span style="text-decoration: underline;">generate</span></em> da classe <em><span style="text-decoration: underline;">Mock</span></em> (que é importada automaticamente no nosso include do autorun.php do Simpletest).</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'simpletest/autorun.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'conexao.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'validator.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
Mock<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Conexao'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Com isso, vamos gerar um clone mockeado da classe <span style="text-decoration: underline;"><em>Conexao</em></span> para podermos usa-la em nossos testes.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'simpletest/autorun.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'conexao.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'validator.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
Mock<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Conexao'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ValidatorTestCase <span style="color: #000000; font-weight: bold;">extends</span> UnitTestCase <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> testValidarSeUsuarioExistir<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MockConexao<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #339933;">...</span><br />
<span style="color: #339933;">...</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Fácil né ?</p>
<h2><span style="font-weight: normal;">Mocks como atores</span></h2>
<p>Agora que sabemos como criar um mock, <strong>vamos aprender a &#8220;imitar&#8221; o que a classe original faz afim de &#8220;simular&#8221; os resultados</strong> que queremos ter para fazer nossos testes passarem.</p>
<p>Os Mocks podem se comportar de duas maneiras:</p>
<ul>
<li>como <strong>Atores (Actors)</strong>, onde o Mock é usado para simular o retorno de propriedades e métodos (e o que vamos usar aqui).</li>
<li>como <strong>Críticos (Critics)</strong>, onde o Mock é usado para guardar e verificar as interações entre os objetos num teste.</li>
</ul>
<blockquote><p>Quando trabalhamos com o Mock apenas como Ator, apenas simulando o retorno de propriedades e métodos, ele é considerado um &#8220;server stub&#8221;, que nada mais é que um objeto que simula um comportamento. Existe uma grande discussão existe em torno disso, mas por enquanto vamos deixar pra lá pois vamos falar sobre os Mocks como uma ferramenta para testes baseados em interação no próximo post e isso vai ficar mais claro.</p></blockquote>
<p>Se analisarmos a classe <em><span style="text-decoration: underline;">Conexao</span></em> novamente, vamos chegar à conclusão que o método que vai ser utilizado em nosso teste será apenas o <em><span style="text-decoration: underline;">query</span></em>: vamos fazer uma consulta à base dados buscando todos os usuários cujo nome seja igual ao parametro que enviarmos ao método <em><span style="text-decoration: underline;">validate</span></em>.</p>
<p><strong>Nosso mock da </strong><em><span style="text-decoration: underline;"><strong>Conexao</strong></span></em><strong> ainda não sabe fazer nada, mas podemos instrui-lo a retornar o que a quisermos</strong>. Por exemplo, em nosso teste chamado <strong>testValidarSeUsuarioExistir</strong> vamos ter que dizer ao mock para retornar sempre um resultado que satisfaça nosso teste. Ou seja, como no exemplo da implementação, se eu envio &#8220;Léo&#8221; ele tem que me devolver um resultado onde &#8220;Léo&#8221; esteja presente, pois queremos testar o comportamento do <em><span style="text-decoration: underline;">validate</span></em> e não o retorno de valor da conexão.</p>
<p>Então, <strong>vamos fazer nosso mock devolver sempre um resultado onde exista o usuário &#8220;Léo&#8221; no resultado</strong>.</p>
<p>Como vimos, nosso método <em><span style="text-decoration: underline;">query</span></em> retorna uma array com os resultados da consulta. Vamos então instruir o mock a retornar sempre um array quando o método query for chamado. Quando o objeto é mockeado, ele ganha vários métodos, entre eles o <strong>s</strong><strong>etReturnValue: esse método diz ao mock &#8220;retorne sempre X resultado quando tal método for chamado&#8221;</strong>.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MockConexao<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$conexao</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setReturnValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query'</span><span style="color: #339933;">,</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'1'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Pronto! Agora podemos testar nosso validate:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'simpletest/autorun.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'conexao.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'validator.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
Mock<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Conexao'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ValidatorTestCase <span style="color: #000000; font-weight: bold;">extends</span> UnitTestCase <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> testValidarSeUsuarioExistir<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MockConexao<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$conexao</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setReturnValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query'</span><span style="color: #339933;">,</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'1'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$validator</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Validator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEqual</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$validator</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>O que aconteceu em nosso teste:</p>
<ul>
<li>Criamos um mock do nossa classe Conexao</li>
<li>Instanciamos esse mock em nosso teste</li>
<li>Instruimos ao mock para que ele devolvesse sempre um array com o usuário Léo quando o método query fosse chamado</li>
<li>Instanciamos nosso validator, passando como parâmetro nossa conexao mockeada</li>
<li>fizemos o teste para verificar se a validação deu certo</li>
</ul>
<p>Fui roda-lo e &#8230;.</p>
<div id="attachment_310" class="wp-caption aligncenter" style="width: 624px"><img class="size-full wp-image-310" title="Opsss! Falhou! :D" src="http://www.leohackin.com.br/wp-content/uploads/2009/12/Captura-de-tela-2009-12-04-às-19.31.10.png" alt="Opsss! Falhou! :D" width="614" height="298" /><p class="wp-caption-text">Opsss! Falhou! <img src='http://www.leohackin.com.br/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p></div>
<p>Temos nosso resultado esperado, afinal <strong>não implementamos ainda nosso método <em><span style="text-decoration: underline;">validate</span></em></strong>. Então, vamos resolver isso:</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">class</span> Validator <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">var</span> <span style="color: #000088;">$conexao</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> __construct<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">conexao</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$conexao</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">function</span> validate<span style="color: #009900;">&#40;</span><span style="color: #000088;">$nome</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #000088;">$resultados</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">conexao</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;select id, nome from users where nome = '<span style="color: #006699; font-weight: bold;">{$nome}</span>'&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span><a href="http://www.php.net/array_search"><span style="color: #990000;">array_search</span></a><span style="color: #009900;">&#40;</span><span style="color: #000088;">$nome</span><span style="color: #339933;">,</span><span style="color: #000088;">$resultados</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<span style="color: #b1b100;">return</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Implementamos uma lógica onde fazemos uma pesquisa ao banco pedindo para selecionar o id e o nome da tabela users onde o nome seja igual ao parâmetro enviado. <strong>A mágica acontece finalmente</strong>: nossa &#8221; falsa conexao&#8221; foi instruída a retornar sempre um array com uma posição apenas, onde o resultado sempre é Léo. <img src='http://www.leohackin.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Agora quando rodamos o teste:</p>
<div id="attachment_315" class="wp-caption aligncenter" style="width: 521px"><img class="size-full wp-image-315" title="Teste do validator agora com a implementação" src="http://www.leohackin.com.br/wp-content/uploads/2009/12/Captura-de-tela-2009-12-05-às-10.25.05.png" alt="Teste do validator agora com a implementação" width="511" height="281" /><p class="wp-caption-text">Teste do validator agora com a implementação</p></div>
<p><strong>Bingo! Nosso teste passou!</strong></p>
<p>Para comprovarmos que o funcionamento do <em><span style="text-decoration: underline;">validate</span></em> está correto, vamos complementar nosso caso de teste adicionando um teste pra verificar se informarmos um usuário que não existe, ele retornar false.</p>
<div class="codecolorer-container php default" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:550px;height:350px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br /></div></td><td><div class="php codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'simpletest/autorun.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'conexao.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">require_once</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'validator.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
Mock<span style="color: #339933;">::</span><span style="color: #004000;">generate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Conexao'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">class</span> ValidatorTestCase <span style="color: #000000; font-weight: bold;">extends</span> UnitTestCase <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> testValidarSeUsuarioExistir<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MockConexao<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$conexao</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setReturnValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query'</span><span style="color: #339933;">,</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'1'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$validator</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Validator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEqual</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$validator</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">function</span> testNaoValidarSeUsuarioNaoExistir<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000088;">$conexao</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> MockConexao<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$conexao</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">setReturnValue</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'query'</span><span style="color: #339933;">,</span><a href="http://www.php.net/array"><span style="color: #990000;">array</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'1'</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'Léo'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000088;">$validator</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Validator<span style="color: #009900;">&#40;</span><span style="color: #000088;">$conexao</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">assertEqual</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$validator</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">validate</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Jeveaux'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Vamos testar denovo e &#8230;</p>
<div id="attachment_322" class="wp-caption aligncenter" style="width: 523px"><img class="size-full wp-image-322" title="Fazendo dois testes" src="http://www.leohackin.com.br/wp-content/uploads/2009/12/Captura-de-tela-2009-12-05-às-12.42.23.png" alt="Fazendo dois testes" width="513" height="281" /><p class="wp-caption-text">Fazendo dois testes</p></div>
<p>Mantemos o nosso mock retornando apenas &#8220;Léo&#8221; nos resultados, mas dessa vez passamos o nome &#8220;Jeveaux&#8221; para procurar e como esperado, ele retornou false, dado que o usuário &#8220;Jeveaux&#8221; não existe. <strong>Show!</strong></p>
<h2><span style="font-weight: normal;">Ufa! Vamos resumir o testamento</span></h2>
<p>O aprendizado de mock objects é um pouco abstrato inicialmente mas com alguma prática se revela uma técnica perfeita e viável para fazemos nossos testes unitários funcionarem de forma correta e independente. A utilização do Mock Object apenas como ator (ou server stub como você lerá muito por ai) é apenas uma parte do poder real de um mock.</p>
<p>Dentro de nosso entendimento, podemos resumir que um<strong><em> mock object é uma imitação de nosso objeto real que podemos manipular de forma fácil e simples para que ele faça exatamente o que quisermos, facilitando assim a implementação de nossos testes unitários e isolando nossas classes</em></strong>.</p>
<p>Algumas leituras legais melhorar o entendimento dos Mock Objects:</p>
<ul>
<li><a href="http://www.simpletest.org/en/mock_objects_documentation.html" target="_blank">Mock Objects no SimpleTest [ doc oficial do SimpleTest ]</a></li>
<li><a href="http://www.improveit.com.br/xp/praticas/tdd/mock_objects" target="_blank">Testes de unidade com mock objects [ ImproveIt ]</a></li>
<li><a href="http://codebetter.com/blogs/jeremy.miller/archive/2005/12/19/135757.aspx" target="_blank">Mock Objects and Stubs: The Bottle Brush of TD</a>D</li>
<li><a href="http://pt.wikipedia.org/wiki/Mock_Object" target="_blank">Mock Objects [ Wikipedia]</a></li>
</ul>
<p>Outra referência bem bacana é o <a href="http://www.jeveaux.com" target="_blank">blog do Jeveaux</a>, meu revisor TDD oficial e grande conhecer de causa. <img src='http://www.leohackin.com.br/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>No próximo post vamos ver como trabalhar com nosso Mock Object em sua forma mais plena e com um exemplo um pouco mais complexo para partir também para o modo Critic. <img src='http://www.leohackin.com.br/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Simbora.</p>

]]></content:encoded>
			<wfw:commentRss>http://www.leohackin.com.br/2009/12/mock-objects-no-simpletest/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>
