A Magia dos Testes Automatizados.

A parte final dos três posts falando sobre testes. Vamos ver uma poderosa ferramenta de automação que é o Apache Ant.

O ANT trabalha através de tarefas, que são especificadas através de um arquivo XML chamado buildfile, onde ao editamos este arquivos definindo as tarefas que desejamos que ele faça, como por exemplo:

Criarmos pastas no sistema operacional, pastas que poderemos usar por exemplo para colocar os executáveis da aplicação que estamos desenvolvendo;

Compilarmos recursivamente todos os fontes na pasta dos arquivos fontes de nosso projeto, colocando na pasta dos executáveis;

Copiarmos arquivos, deletarmos arquivos, listarmos arquivos;

Fazer conexões com bancos de dados, utilizarmos comandos do sistema, fazer log de nossos projetos, dentre várias outras tarefas.

O que demonstrarei é como o Ant automatiza tarefas necessárias para que sua aplicação esteja pronta para a implantação, distribuição, etc. Nesse post, abordaremos as seguintes tarefas a serem executadas:

  • Deleção e criação de diretórios.

  • Definir as libs que serão incluídas no projeto.

  • Compilar suas classes.

  • Definir seus testes e executá-los.

  • E o objetivo final, que é gerar o arquivo .war.

Aproveitando a estrutura do projeto já desenvolvido nos outros posts, <link aqui referenciando os posts antigos>vamos criar o arquivo build.xml na raiz do projeto. A estrutura do arquivo xml segue uma estrutura uniforme, mais ou menos dessa forma:

<project name="nome_projeto" basedir="." default="alvo1">

        <target name="alvo1">

             <tarefa1 />

             <tarefa2 />

        </target>

        <target name="alvo2">

              <tarefa1 />

              <tarefa2 />

        </target>

        <target name="alvo3">

              <tarefa1 />

        </target>
</project>
A raiz do arquivo é o elemento project, que possui os atributos name(nome do projeto, ah vá..),basedir(O diretório base a partir do qual os demais caminhos para arquivos e diretórios serão calculados. O “.” se refere ao diretório atual), default(Se você executar o Ant via Terminal e não for especificado nenhum alvo, o alvo declarado aqui será executado).

Os elementos filhos, que são os target, e neles podem possuir uma ou mais tarefas(tasks) a serem executadas (novamente – criar, renomear ou excluir diretórios, compilar e empacotar arquivos, etc. ).

Pois bem, vamos ao “jeitão” do nosso XML. Vamos listar as tarefas que serão executadas e algumas particularidades:

1.Declaro meu classpath (as libs que serão utilizadas no meu projeto).
<path id="classpath">
        <pathelement location="${classes.dir}" />
        <fileset dir="${lib.root}">
              <include name="*.jar" />
        </fileset>
</path>
2.Target, ele exclui o diretório que é criado pelo ant (target). E serão recriados os diretorios onde serão armazenados as classes compiladas e os testes compilados, respectivamente.
<target name="clean">
      <delete dir="${target.dir}"/>
      <mkdir dir="${classes.dir}"/>
      <mkdir dir="${test.classes.dir}"/>
</target>
3. Target, as classes e os testes serão compilados e “jogados” para seus respectivos diretórios, que foram criados no target anterior.
<target name="compile" depends="clean">
        <javac srcdir="${basedir}" destdir="${classes.dir}" >
         <classpath>
            <path refid="classpath"/>
         </classpath>
        </javac>
     <!-- Compila Test classes -->
        <javac destdir="${test.classes.dir}" srcdir="${test.source.dir}">
      <classpath>
              <path refid="classpath"/>
      </classpath>
        </javac>
</target>
4.Próximo target, onde será executado os testes. O Ant gerará um relatório, no formato que você definir na tag “formatter”, armazenando em algum diretório de sua preferência. Adicionamos o classpath novamente e definimos o batchtest (no qual todas as classes com o padrão **/**Teste.java, serão reconhecidas como classe de teste e executadas como tal).
<target name="teste" depends="test-mysql">
        <mkdir dir="${test.report.dir}"/>
        <junit printsummary="on" fork="no" haltonfailure="true" haltonerror="true">
              <sysproperty key="basedir" value="." />
              <formatter type="xml" />
              <classpath refid="classpath"/>
              <batchtest todir="${test.report.dir}">
                    <!-- Unit Tests -->
                    <fileset dir="${test.source.dir}/unit">
                           <include name="${test.source.dir}/unit/${test.pattern}" />
                    </fileset>
                    <!-- Integration Tests -->
                    <fileset dir="${test.source.dir}/integration">
                           <include name="${test.source.dir}/integration/${test.pattern}" />
                    </fileset></p>

              </batchtest>
       </junit>
</target>
5.Por fim, se todas as etapas forem construídas sem erros e os testes passarem, então criaremos o arquivo .war para realizar o deploy no servidor.
<target name="buildwar" depends="teste">
         <javac srcdir="${basedir}" destdir="${classes.dir}">
               <classpath refid="classpath"/>
         </javac>

         <mkdir dir="${war.dir}" />
         <war destfile="${war.dir}/VRaptorTestesAutomatizados.war" webxml="${web.xml}">
              <classes dir="${classes.dir}" />
              <lib dir="${lib.root}"></lib>
              <fileset dir="WebRoot/">
                   <include name="META-INF/**"/>
                   <include name="*.jsp" />
                   <include name="*.html" />
              </fileset>
         </war>
</target>
*Todos os caminhos ${alguma-coisa} está definido no arquivo build.properties, definido na segunda linha.
Rodando o seu script Buildfile, vamos ao resultado no console:
E ao final, como prova que realmente você fez o que tinha que fazer :). Fiz o deploy no servidor e vamos ao resultado no browser.
Sinal que sua aplicação deu certo. Compilamos nossas classes, fazemos nossos testes e geramos nosso .war. Isso é só um pouco que essa poderosa ferramenta, que é o Ant pode fazer. Até os próximos posts.

DESENVOLVENDO PARA ANDROID: MEXENDO COM MAPAS

Opa, voltando a falar sobre Android, vamos falar de um negócio bacana, que é brincar com o GMap.

Mas para manipularmos mapas, teremos que ter uma Google API Key . Para consegui-la, entre no link. Nele, você deve colocar seu fingerprint, que pode ser conseguido através do comando:

keytool -list -alias meualias -keystore minhachave.jks

o google vai ti devolver uma tela aonde você terá um trecho de código que será usado na sua view de mapas.


<com.google.android.maps.MapView

     android:layout_width="fill_parent"

     android:layout_height="fill_parent"

     android:apiKey="0BN1gWBPEYDQluZey4KPKZH_C4AMH2sG02G1GLg"

     android:id="@+id/map_view"/>

Vamos ao momento feliz, mão na massa!!

O desafio será o seguinte: Me achar no mapa. Mostrando a minha localização pelo gps.

I) Temos que criar uma o mapa.xml dentro do res/layout, uma vez que recebemos o código do site do google que exibi acima.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="fill_parent"

          android:layout_height="fill_parent">

          <com.google.android.maps.MapView

               android:layout_width="fill_parent"

               android:layout_height="fill_parent"

               android:apiKey="0BN1gWBPEYDQluZey4KPKZH_C4AMH2sG02G1GLg"

               android:id="@+id/map_view"/>

</LinearLayout>

II) Como já foi visto , uma tela é uma Activity. Mas neste caso será um MapActivity pois queremos todas as funcionalidades que um mapa pode nos dar. Vamos criar uma classe Mapa.java que extenda MapActivity:


@Override

protected boolean isRouteDisplayed() {

     return false;

}

@Override

protected void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        setContentView(R.layout.mapa);

        mapView = (MapView) findViewById(R.id.map_view);

        mapController = mapView.getController();

        //Pegamos os controles necessários do nosso sistema.

        mapView.setSatellite(true);

        mapView.setStreetView(true);

        mapView.displayZoomControls(true);

        mapController.setZoom(14);

        final List<Overlay> overlays = mapView.getOverlays();

        //Criamos um overlay, assim podemos nos achar no mapa e ainda mostrar o recurso de bússola(plus!).

        MyLocationOverlay myLocationOverlay = new MyLocationOverlay(this, mapView);

        overlays.add(myLocationOverlay);

        myLocationOverlay.enableCompass();

        myLocationOverlay.enableMyLocation();

        //E temos que atualizar o nosso sistema, quando tivermos em movimento. Para isso, criamos um listener, e //antes temos que inicializar o GPS para que possa escolher o melhor serviço de posicionamento disponível.

        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        Criteria criteria = new Criteria();

        criteria.setAccuracy(Criteria.ACCURACY_COARSE);

        criteria.setAltitudeRequired(false);

        criteria.setCostAllowed(true);

        criteria.setPowerRequirement(Criteria.POWER_HIGH);

        String provider = locationManager.getBestProvider(criteria, true);

        Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

        atualizarMeuLocal(location);

}

        LocationListener locationListener = new LocationListener() {

              public void onStatusChanged(String provider, int status, Bundle extras) {

              }

              public void onProviderEnabled(String provider) {

              }

              public void onProviderDisabled(String provider) {

                   atualizarMeuLocal(null);

              }

              public void onLocationChanged(Location location) {

                    atualizarMeuLocal(location);

               }

         };

              //Socilitamos que rode o listener a cada 2 segundos ou uma diferença de 20 metros.

               locationManager.requestLocationUpdates(provider, 2000, 20, locationListener );

   }

          //Agora temos que criar o nosso método atualizarMeuLocal(Location location), repare que ele o location que //usará para localizar o seviço e buscar a posição.

          private void atualizarMeuLocal(Location location) {

                if(location != null){

                     Double geoLat = location.getLatitude() * 1E6;

                     Double geoLong = location.getLongitude() * 1E6;

                     GeoPoint point = new GeoPoint(geoLat.intValue(), geoLong.intValue());

                     //Sempre que o o método for chamado, ele irá mover o nosso mapa para a posição atual.

                     mapController.animateTo(point);

                 }

            }

Testes de Integração: Validando ainda mais sua aplicação

A próxima etapa nos artigos sobre teste. Vamos aos chamados Testes de Integração. Como tradição, vamos a “definição wiki de ser”. “teste de integração é a fase do teste de software em que módulos são combinados e testados em grupo.”.

Bem, não é a definição mais clara que podemos encontrar. Mas calma, vejamos desse jeito:

Nos testes unitários, cada módulo do sistema será testado individualmente. Sem influência de outras classes do sistema e se possuir alguma dependência, nós criamos Mocks que simulem o funcionamento dessa dependência.

Nos testes de integração, nós queremos que os módulos sejam testados de forma que interajam com o restante do sistema, oferecendo dependências reais para garantir que elas funcionem em conjunto.

Imagine a situação de um cadastro (aquele crud “basicão”). Com o Teste de Unidade, você cria um teste para as regras de negócios, outro para as classes de persistência com o banco e assim por diante. Nos Testes de Integração, você testa somente o método Inserir, ou Pesquisar ou Atualizar e deixa que os módulos si relacionem de verdade, sem Mock Objects, sem nenhum artifício qualquer.

Para realizar nossos testes, novamente utilizaremos o JUnit,  Spring Framework, e o DBUnit, que é uma extensão do JUnit que oferece funcionalidades específicas para testes envolvendo banco de dados.

Primeiramente você pode encontrar uma melhor explicação sobre o DBUnit aqui. O DBUnit necessita de um arquivo xml que funcionará como o conjunto dos dados que serão inseridos no banco antes dos testes rodarem, afim de garantir que os dados que serão usados estarão presentes no banco. Tomamos o exemplo da tabela Filme, com os campos, codigo, titulo e ano.

<dataset>

 <filme codigo="10" titulo="HANNIBAL" ano="2002"/>
 <filme codigo="20" titulo="RED DRAGON" ano="2003"/>
 <filme codigo="30" titulo="ADVOGADO DO DIABO" ano="1997"/>
 <filme codigo="35" titulo="PERFUME DE MULHER" ano="1991"/>
 <filme codigo="40" titulo="THE GODFATHER" ano="1970"/>

</dataset>]
Mas antes de implementar-mos nossos testes, precisamos configurar o dataSource e adicionar o dbUnit no Spring.
<context:component-scan base-package="com.wordpress.yuriadamsmaia.integration.base.dbunit"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.SingleConnectionDataSource" >

<property name="driverClassName" value="com.mysql.jdbc.Driver" />
 <property name="url" value="suaURL" />
 <property name="username" value="SEUUSERNAME" />
 <property name="password" value="SUAPASSWORD" />
 <property name="suppressClose" value="true" />
 </bean>
Antes de escrever os testes, vamos conhecer o que iremos testar. Para não estender muito, iremos limitar a testar um único método(no caso o método pesquisar).  *
@Service("filmeService")
public class FilmeServiceImpl implements FilmeService{
 @PersistenceContext
 private EntityManager entityManager;
 private Session getSession() {
 return ((Session) entityManager.getDelegate());
 }
@SuppressWarnings("unchecked")
@Override
public List<Filme> pesquisar(Filme filme) {
Criteria criteria = getSession().createCriteria(Filme.class);

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

if (!StringUtils.isEmpty(filme.getTitulo()))
criteria.add(Restrictions.like("titulo", "%" + filme.getTitulo() + "%"));
if (!StringUtils.isEmpty(filme.getAno()))</p>
criteria.add(Restrictions.like("ano", "%" + filme.getAno() + "%"));

criteria.addOrder(Order.asc("codigo"));
return criteria.list();
}

}
* Estamos utilizando o hibernate e JPA API para  a persistência. Então toda configuração no Spring para permitir essa integração será disponivel no final do post.

Escrevendo nosso teste:

O teste terá os seguintes passos:
  1. Limpar e Carregar os dados antes para nossos métodos de teste;
  2. Realizar os métodos de teste, onde nós iremos comparar se o valor está conforme o arquivo XML.
A classe FilmeServiceImplTeste.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
 "file:./WebRoot/WEB-INF/config/spring/applicationContext.xml",
 "file:./WebRoot/WEB-INF/config/spring/applicationContext-persistence-test.xml"
})
public class FilmeServiceImplTeste {
private static final String DATASET = "./test/com/wordpress/yuriadamsmaia/integration/base/dbunit/xml/FilmeServiceImplTeste.xml";
@Autowired DbUnitManager dbUnitManager;
@Autowired FilmeService filmeService;

 @Before
 public void setUp() {
 dbUnitManager.cleanAndInsert(DATASET);
 }
Anotamos a classe com @RunWith(SpringJUnit4ClassRunner.class) para o JUnit rodar os testes com o Spring Test. E também anotamos a classe com o @ContextConfiguration(locations={“file:./WebRoot/WEB-INF/config/spring/applicationContext.xml”, “file:./WebRoot/WEB-INF/config/spring/applicationContext-persistence-test.xml”}), que define os nossos arquivos XML onde estão as configurações, com o detalhe que criamos um outro XML(applicationContext-persistence-test.xml) somente para os testes.
O método cleanAndInsert(DATASET) da Interface DbUnitManager que está sendo injetada, faz com que sempre quando o teste é iniciado,  base de dados é limpa e os dados são re-inseridos(evitando duplicata de dados, ou seja, lixo).
public void cleanAndInsert(String dbUnitXmlPath) {

try {
 IDatabaseConnection dbconn = this.getDbUnitConnection();
 DatabaseOperation.CLEAN_INSERT.execute(dbconn, this.getDataSetFrom(dbUnitXmlPath));
 dbconn.close();
 } catch (Exception e) {
 e.printStackTrace();
 throw new RuntimeException(e);
 }
 }
private IDatabaseConnection getDbUnitConnection() throws      DatabaseUnitException, SQLException {
IDatabaseConnection dbconn = new DatabaseConnection(this.getConnection());
dbconn.getConfig().setProperty(DatabaseConfig.PROPERTY_DATATYP E_FACTORY, new MySqlDataTypeFactory());
return dbconn;

}
 private IDataSet getDataSetFrom(String dbUnitXmlPath) throws IOException,
 DataSetException, FileNotFoundException {
 return new FlatXmlDataSetBuilder().build(new FileInputStream(dbUnitXmlPath));
 }
Agora os testes. Daqui pra frente , o raciocínio não muda dos testes unitários.
@Test
 public void deveriaPesquisarFilmesSemCamposEspecificados(){
 Filme filme = new Filme();
 List<Filme> pesquisa = filmeService.pesquisar(filme);
 verificaListaRetornoPesquisa(pesquisa);
 assertEquals("deveria estar trazendo a lista de tamanho correto", pesquisa.size(), LISTA_TAMANHO);
 }
private void verificaListaRetornoPesquisa(List<Filme> pesquisa) {</p>
assertNotNull("nao deveria ser nula", pesquisa);</p>
assertFalse("nao deveria retornar a lista vazia", pesquisa.isEmpty());</p>
assertEquals("deveria estar trazendo a lista correta", pesquisa.get(0).getTitulo(), FILME_TITULO);</p>
assertEquals("deveria estar trazendo a lista correta", pesquisa.get(0).getAno(), FILME_ANO);</p>

}

De fato, como estou passando como argumento do pesquisar um objeto filme com todos os campos vazios, o método retorna todos os registros na tabela. Fazemos as verificações, se a lista retornada não é nula, não é vazia, verificamos se o primeiro elemento da lista retornada está de acordo com o arquivo xml. E finalmente verificamos o tamanho da lista, a fim de saber se todos os elementos foram pesquisados.

De forma análoga, podemos realizar uma pesquisa limitada por algum campo, por exemplo o título.

@Test
public void deveriaPesquisarFilmesPeloTitulo(){
 Filme filme = new Filme();
 filme.setTitulo(FILME_TITULO);
 List<Filme> pesquisa = filmeService.pesquisar(filme);
 verificaListaRetornoPesquisaPeloTitulo(pesquisa);
}
private void verificaListaRetornoPesquisaPeloTitulo(List<Filme> pesquisa) {
 assertNotNull("nao deveria ser nula", pesquisa);
 assertFalse("nao deveria retornar a lista vazia", pesquisa.isEmpty());
 assertEquals("deveria estar trazendo a lista correta", pesquisa.get(0).getTitulo(), FILME_TITULO);
}
Espero ter passado o conhecimento que tenho adquirido nas ultimas semanas sobre Testes. O projeto vai estar disponível no github para download. E o próximo passo será automatizá-los, via Apache Ant.
link para download: https://github.com/yuriadams/VRaptorTestesAutomatizados

Com VRaptor e Mockito é muito mais fácil testar!

E ai negada, depois de um tempão sem postar nada(Faculdade e o novo estágio agradecem), estou de volta para falar um pouco sobre um assunto que tenho dando bastante  ênfase que são os testes. Pretendo escrever dois artigos falando sobre tal. O primeiro a seguir abordando os testes de unidade e o próximo a respeito dos testes de integração. Então vamos lá.

           “Usando TDD, quando acabamos, realmente acabamos. Ou seja, dificilmente temos que retornar ao código futuramente para corrigir falhas, pois possíveis falhas já foram detectadas e corrigidas durante a confecção dos testes.”
Com essa citação que pode ser encontrada no site da ImproveIt, damos início a um dos temas “quentes” do momento que são os testes. Mas o que é esse TDD?Bem, TDD (Test Driven Development) é uma das práticas abordadas na metodologia XP, que se baseia em escrever os testes antes de programarmos o código-fonte. Legal essa idéia do TDD, mas o post irá focar nos testes, especificamente nos testes de unidade ou testes unitários. Então XP fica para a próxima.
O teste unitário ou de unidade é uma modalidade de testes que se concentra na verificação da menor unidade de código funcional do projeto de software. Como estamos no mundo OO, essa menor unidade pode ser entendida a um objeto ou mesmo a um comportamento do mesmo, reagindo a um estimulo (métodos da classe). Com entradas que são parâmetros e as saídas são o valores de retorno, exceções ou o estado do objeto.
O que será demonstrado nesse post, será desde uma explicação de testes, com exemplos simples sobre testes unitários. Até aprofundarmos mais, mostrando testes em uma classe de controle do VRaptor, passando pelo conceito de Mock Object, abordando as facilidades que  VRaptor traz, afim de “Mockar” os objetos do framework.
Para implementar os testes usaremos o bastante conhecido JUnit, ele escreve testes em Java e se integra facilmente com qualquer IDE (Eclipse, NetBeans, whatever).
              Vamos a uma classe simples de teste do JUnit:
public class MathTeste {

@Test

public void somaTeste(){

        Assert.assertEquals(9, 5+4);

}

}

A primeira vista:
1. Nós dizemos ao Junit que aquele método é um teste pela annotation @Test.
2. Eu quero saber se o resultado 5+4 é IGUAL a 9(dã!!), daí o assertEquals. Não para por ai, a <a href=”http://junit.sourceforge.net/javadoc/org/junit/Assert.html”>classe Assert</a> possui inúmeros métodos de verificação.

E ao rodar o teste, o plugin do Junit na IDE(Eclipse no caso), “cospe” o resultado. Trata de um sinal verde, se seu teste passou. Vermelho se não passou (legal né?).

Ok. Passando a parte introdutória, vamos ao VRaptor. O VRaptor é um framework MVC em Java focado no desenvolvimento rápido e simples, e na fácil manutenção do código. Mais uma definição wiki.</div>
Beleza, mas nosso foco ainda não é entrar em detalhes sobre o VRaptor e como ele trabalha, mas sim TESTES. Assim vou mostrar a nossa classe de controller a ser testada(Limitaremos somente a funcionalidade de pesquisa).</div>

@Resource
public class FilmeController {

      private final Result result;
      private FilmeService filmeService;
      private Validator validator;

      public FilmeController(Result result, FilmeService filmeService, Validator validator) {
              this.result = result;
              this.filmeService = filmeService;
              this.validator = validator;
      }

      @Path("/filme")
      public void index(){
      }

      @Get
      @Path("/filme/pesquisa")
      public void pesquisa(Filme filme){
           List loadFilme = null;
           try{
                loadFilme = filmeService.pesquisar(filme);
                if(loadFilme.isEmpty()){
                      result.include("notice", "Nenhum produto encontrado!!");
                }
                result.include("filmes", loadFilme);
                result.forwardTo(this).index();
          }catch(Exception e){
                result.include("erros", e.getMessage());
          }
      }
            Show galera. Classe controller mostrada, agora vamos ao FilmeControllerTeste.java, nossa classe que realizará o teste unitário do FilmeController.java.
private Result result;
private Validator validator;
private FilmeController filmeController;

@Mock private FilmeService filmeService;
            Criamos esses objetos para simular o comportamento da classe a ser testada. Uma breve explicação.  Result, que é um componente do VRaptor que consegue mudar o resultado do seu método. Similar a classe HttpRequest da Api Servlet. A Interface Validator, que é passada como parâmetro no construtor da classe, oferece meios para realizar validações no seu controller.
             E esse Mock. “WTF” Mock?
Mock objects são objetos que simulam o comportamento de objetos reais. Mas pra que isso? Serve para prender o escopo dos seus testes. Por exemplo, se você esta fazendo um teste em uma classe de controle e o método desta classe invoca um método de uma classe de serviço que faz uma consulta no banco, você deve usar um Mock para simular o objeto desta outra classe, simulando assim esta consulta, pois a consulta será testada no momento em que o teste para o seu método for criado.

             Antes de implementar o primeiro teste, vamos inicializar.. é.. o que precisamos pra começar os testes(A annotation @Before  do JUnit é utilizada justamente para isso).

  • Todos os Mocks (utilizando o Mockito API, para trabalhar com os mocks).
  • Result e Validator(Vraptor já disponibiliza os mocks para esses objetos).
</pre>
@Before
public void setUp(){
      MockitoAnnotations.initMocks(this);
      result = new MockResult();
      validator = new MockValidator();
      filmeController = new FilmeController(result, filmeService, validator);
}

               E finalmente vamos começar a brincadeira. Primeiro vamos ao “happy day”, o que deve acontecer se a pesquisa for bem sucedida.

//obs: Fazemos os imports estásticos afim de melhorar a leitura do código:
// import static org.junit.Assert.*;
// import static org.mockito.Mockito.*;
// import static org.mockito.Matchers.any;

@Test
public void deveriaPesquisarFilmes(){
        when(filmeService.pesquisar(any(Filme.class))).thenReturn(new ArrayList());
        filmeController.pesquisa(any(Filme.class));

        assertTrue("deve haver uma lista de Filmes", result.included().containsKey("filmes"));
        assertFalse("n‹o deve exibir nenhuma msg de erro)", result.included().containsKey("erros"));
}
              Teste passando, vamos aos porquês. A Api Mockito eh bem intuitiva, ela possui  métodos estáticos de fácil entendimento, senão vejamos.  “Quando(when) um filmeService pesquisar (filmeService.pesquisar(…)) qualquer filme (any(Filme.class)), então me retorne uma lista de filmes (thenReturn(new ArrayList<Filme>());). Mais intuitivo que isso impossível. Importante é você entender a semântica(feeling) da coisa e saber(no sangue) o comportamento da sua classe. O resto é detalhe de sintaxe.”
Vamos ao revés.
</pre>
@Test
public void deveriaTratarORetornoDeUmaListaNull(){
      when(filmeService.pesquisar(any(Filme.class))).thenReturn(null);
      filmeController.pesquisa(any(Filme.class));

      assertTrue("deve exibir uma mensagem de erro", result.included().containsKey("erros"));
      assertFalse("n‹o deve exibir nenhuma msg de aviso)", result.included().containsKey("notice"));
      assertFalse("nao deve haver uma lista de Filmes", result.included().containsKey("Filmes"));
}
             Testando o que pode acontecer se o método não for bem sucedido, alguma exceção lançada, ou seja algo dando errado, é o ponto chave dos testes. Você prever o que pode dar errado no seu código(aqui estou verificando um único problema que possa ocorrer, por questão de não me estender ainda mais) e na mesma hora tratar e corrigir esse erros, vão lhe poupar tempo depois que seu sistema estiver em produção. Afinal, time is money. Não estou afirmando que com os testes, você estará segurado 100% de erros, mas certamente eles demorarão mais a ocorrer e a manutenção se tornará menos dolorosa. Sem falar na melhoria do design do seu código com o uso de testes(principalmente se você estiver usando TDD – Leia Clean Code!).
REFERÊNCIAS:
O código completo pode ser baixado no meu github: http://www.github.com/yuriadams.
Seguir

Obtenha todo post novo entregue na sua caixa de entrada.