Ola pessoal.Hoje irei demonstrar como implementar testes unitarios com a utilizacao do PHPUnit.Primeiro gostaria de complementar que, quem me incentivou a comecar a escrever sobre este assunto, foi Paulo Victor, meu parceiro de blog e de grande amizade.... agora vamos codar!!Dada as seguintes classes...class Host{ /** get hostname by cookie * * @return string */ public function getHost() { // get hostname by cookie return $_COOKIE['host_cookie']; }}----------------------------------------------------class Options{ /** * @var Host */ private $host; public function __construct(Host $host) { $this->host = $host; } /** * @return array */ public function getOptions() { $options = array(); switch($this->host->getHost()){ case 'site.host2': $options['CACHE_ENABLED'] = false; break; case 'site.default': $options['CACHE_ENABLED'] = true; break; } return $options; }}Acabei de desenhar o cenario que iremos enfrentar.hora do entendimento.Temos duas classes, a Host e a Options.Para que voces entendam o contexto, a classe Host e responsavel por acessar uma informacao que esta no cookie, que no caso e o indice: 'host_cookie'.Ja a classe Options, utiliza da informacao que recebera de uma instancia de Host, para retornar as opcoes, que e de sua responsabilidade.Options recebe como injecao de dependencia, um objeto Host no construtor.OBS. : A intencao e realizar teste unitario na classe Options, iremos assumir que a classe Host ja esta coberta por testes.Agora vai a primeira proposta para a classe de teste OptionsTest que obviamente ira testar a classe Options:require_once ZF2_PATH. '/module/Tutorial/src/Tutorial/Component/Host/Options.php';class OptionsTest extends PHPUnit_Framework_TestCase{ public function testGetOptions() { $expected = array('CACHE_ENABLED' => true); $_COOKIE['host_cookie'] = 'site.default'; $option = new Options(new Host()); $result = $option->getOptions(); $this->assertEquals($expected, $result); }}Entendendo o codigo...Nesta classe de teste, apenas instanciamos a classe Options, passando uma nova instancia de Host, e realizamos a chamada do metodo getOpions().Como sabemos que a classe Host ira buscar um valor na variavel global $_COOKIE, estamos definindo o valor necessario previamente.OBS.: Quando testamos compotamento, ja sabemos o que esperamos como retorno, entao so temos que verificar se o retorno do metodo e o esperado, para isso utilizamos os metodos do PHPUnit, no codigo acima, foi utilizado o metodo assert, que verifica se ambos os argumentos sao iguais.Agora a refatoracao.....No exemplo mostrado para a classe de teste(OptionsTest), estamos dependendo do comportamento de outra classe, a Host, e isso nao pode acontecer, pois estamos testando a classe Options e nao podemos depender de fatores externos....Com isso iremos utilizar um Mock.Um Mock, e um objeto que se passa por uma instancia de outra classe, e seus comportamentos serao pre definidos.Iremos criar um mock para a classe Host, que e dependencia para o construtor da classe Options, com isso nosso teste nao dependera da instancia real de um objeto Host, pois o codigo de teste ira utilizar o nosso Mock e nunca ira executar a classe Host.OptionsTest (FINAL)require_once ZF2_PATH. '/module/Tutorial/src/Tutorial/Component/Host/Options.php';require_once ZF2_PATH. '/module/Tutorial/src/Tutorial/Component/Host.php';class OptionsTest extends PHPUnit_Framework_TestCase{ public function testGetOptions() { $expected = array('CACHE_ENABLED' => true); $mockedHost = $this->getMock('Host', array('getHost'), array(), '', false); $mockedHost->expects($this->once()) ->method('getHost') ->will($this->returnValue('site.default')); $option = new Options($mockedHost); $result = $option->getOptions(); $this->assertEquals($expected, $result); }}OBS.: Ainda poderiamos explorar muito esse teste, pois teriamos que prever todas as situacoes para o metodo getOptions(), mas o post ficaria muito extenso.Por enquanto e so pessoal, provavelmente irei