78
Exercícios TDD exercícios extraído de curso da Caelum

Exercicios_TDD

Embed Size (px)

DESCRIPTION

Exercícios sobre TDD apresentados em sala de aula.A técnica de TDD representa uma inovação trazida pelos métodos ágeis, e que vem melhorar muito a qualidade dos projetos de desenvolvimento de software.

Citation preview

Exercícios TDDexercícios extraído de curso da Caelum

JUnitBotão direito no projetoBuild PathAdd librariesselecione JUnit

PastasEm java é comum usar pastas para código de produção no source folder.

Criar um segundo source folder para testes

criar a mesma estrutura de pastas para os testes, espelhando a produção.

Anatomia do método de testeO nome deve refletir um comportamento esperadonão pode ser estáticonão deve receber parâmetros

@Testusar a anotação antes do método de teste

deve ser:@Testpublic void deve_apresentar_um_comportamento_especifico() {

...}

Anatomia de um Teste- Constroi Cenário

Quais elementos externos são necessários paraexercitar o comportamento

- Executa açãoinvoca o comportamento que se deseja testar

- Verifica saídaEstabelece expectativas do comportamentoQuais são as pós condições?

AssertExpectativa de igualdade

assertEquals(esperado, recebido);

import static org.junit.Assert.assertEquals;import org.junit.*;

para valores doubleassertEquals(esperado, recebido, delta=0.0001);

@Before e @After ...@Before

método a ser executado antes de todos os testes

@Aftermétodo a ser executado depois de todos os testes

@BeforeClassmétodo a ser executado antes da classe de testes

@AfterClassmétodo a ser executado após a classe de testes

Download fontes

http://bit.ly/caelum-testes-cap1

Lancepackage br.com.caelum.leilao.dominio;public class Lance {

private Usuario usuario;private double valor;

public Lance(Usuario usuario, double valor) {this.usuario = usuario;this.valor = valor;

}

public double getValor() {return this.valor;

}

public String toString() {return usuario.getNome()+"("+valor+")";

}}

Leilaopackage br.com.caelum.leilao.dominio;import java.util.ArrayList;import java.util.List;public class Leilao {

private String produto;private List<Lance> lances;

public Leilao(String produto) {this.produto = produto;this.lances = new ArrayList<Lance>();

}public void propoe(Lance lance) {

if(lance.getValor() <= 0)throw new RuntimeException("Valor não pode ser negativo ou zero");

this.lances.add(lance);}public List<Lance> getLances() {

return lances;}

}

Usuariopackage br.com.caelum.leilao.dominio;

public class Usuario {private String nome;

public Usuario(String nome) {this.nome = nome;

}

public String getNome() {return nome;

}

public String toString() {return nome;

}}

ExercícioDado um leilão, devemos saber qual o maior lance que foi dado.

Criar uma classe AvaliadorCriar um método avalia(Leilao)

Criar um método getMaiorLance()Criar uma classe AvaliadorTest (pacote leilao.test)adicionar 3 lances avaliar se o maiorLance está coerente

Estratégia1. Dado um leilao, é preciso que um Avaliador possa avaliar o leilao, pois deve ser possível consultar ao Avaliador qual foi o maior lance:teste:

no pacote: leilao.teste a classe AvaliadorTestecriar 3 Usuárioscriar 1 Leilaocriar 3 lances (300, 400, 250)criar um Avaliador: leiloeiroexecutar leiloeiro.avalia()testar se o maiorLance() funciona

Resultado@Testpublic void deve_saber_qual_o_maior_lance_dado() {

// parte 1: contextoAvaliador leiloeiro = new Avaliador();Usuario joao = new Usuario("Joao");Usuario jose = new Usuario("Jose");Usuario maria = new Usuario("Maria");

Leilao leilao = new Leilao("Playstation 3 Novo");leilao.propoe(new Lance(joao, 250.0));leilao.propoe(new Lance(jose, 300.0));leilao.propoe(new Lance(maria, 400.0));

// parte 2: açãoleiloeiro.avalia(leilao);

// parte 3: validacaoassertEquals(400.0, leiloeiro.getMaiorLance(), 0.00001);

}

ProduçãoNo pacote: leilao.servico

Avaliador.avalia()maior = Double.NEGATIVE_INFINITY;calcula o maior de todos;

getMaiorLance()

Execução (control-f11)

@Beforeprivate Avaliador leiloeiro;private Usuario joao;private Usuario jose;private Usuario maria;

@Beforepublic void criaAvaliador() {

this.leiloeiro = new Avaliador();joao = new Usuario("Joao");jose = new Usuario("Jose");maria = new Usuario("Maria");

}

Resultado@Testpublic void deve_saber_qual_o_maior_lance_dado() {

// parte 1: contextoLeilao leilao = new Leilao("Celular Usado");leilao.propoe(new Lance(joao, 250.0));leilao.propoe(new Lance(jose, 300.0));leilao.propoe(new Lance(maria, 400.0));

// parte 2: açãoleiloeiro.avalia(leilao);

// parte 3: validacaoassertEquals(400.0, leiloeiro.getMaiorLance(), 0.00001);

}

ExercícioDado um leilão, devemos saber qual o menor lance que foi dado.

Criar um método getMenorLance()

Criar uma classe AvaliadorTest (pacote leilao.test)

Resultado@Testpublic void deve_saber_qual_o_menor_lance_dado() {

// parte 1: contextoLeilao leilao = new Leilao("Playstation 3 Novo");leilao.propoe(new Lance(joao, 250.0));leilao.propoe(new Lance(jose, 300.0));leilao.propoe(new Lance(maria, 400.0));

// parte 2: açãoleiloeiro.avalia(leilao);

// parte 3: validacaoassertEquals(250.0, leiloeiro.getMenorLance(), 0.00001);

}

ExercicioFazer um teste mudando ordem dos valores

Resultado@Testpublic void deveEntenderLancesForaDeOrdem() {

// parte 1: contextoLeilao leilao = new Leilao("Playstation 3 Novo");leilao.propoe(new Lance(joao, 250.0));leilao.propoe(new Lance(jose, 400.0));leilao.propoe(new Lance(maria, 300.0));

// parte 2: açãoleiloeiro.avalia(leilao);

// parte 3: validacaoassertThat(leiloeiro.getMenorLance(), equalTo(250.0));assertThat(leiloeiro.getMaiorLance(), equalTo(400.0));

}

ExercícioDeve ser possível obter a média dos lances

Resultado@Testpublic void deve_saber_qual_a_media_dos_lances() {

// parte 1: contextoLeilao leilao = new Leilao("Playstation 3 Novo");leilao.propoe(new Lance(joao, 250.0));leilao.propoe(new Lance(jose, 300.0));leilao.propoe(new Lance(maria, 400.0));

// parte 2: açãoleiloeiro.avalia(leilao);

// parte 3: validacaoassertEquals(316.666, leiloeiro.getMedia(), 0.001);

}

Produçãoclass Avaliador {private double maiorDeTodos = Double.NEGATIVE_INFINITY;private double menorDeTodos = Double.POSITIVE_INFINITY;private double media = 0;

public void avalia(Leilao leilao) {double total = 0;for(Lance lance : leilao.getLances()) {

if(lance.getValor() > maiorDeTodos) maiorDeTodos = lance.getValor();if(lance.getValor() < menorDeTodos) menorDeTodos = lance.getValor();total += lance.getValor();

}media = total / leilao.getLances().size();

}

public double getMaiorLance() { return maiorDeTodos; }public double getMenorLance() { return menorDeTodos; }public double getMedia() { return media; }}

Classes de equivalênciaVários teste mudando os valores vale a pena?

Ordem CrescenteOrdem DecrescenteOrdem RandômicaCom apenas um lanceSem lancesLance Negativo

Exercíciodeve entender leilao com apenas um lance

Resultado@Testpublic void deveEntenderLeilaoComApenasUmLance() {

Leilao leilao = new Leilao("Playstation");

leilao.propoe(new Lance(joao, 1000.0));

leiloeiro.avalia(leilao);

assertEquals(1000, leiloeiro.getMaiorLance(), 0.0001);assertEquals(1000, leiloeiro.getMenorLance(), 0.0001);

}

ExercícioCalcular os três maiores lancesretorne um List<Lance>

Resultado@Testpublic void deveEncontrarOsTresMaioresLances() {

Leilao leilao = new Leilao("Playstation 3 Novo");leilao.propoe(new Lance(joao, 100.0));leilao.propoe(new Lance(maria, 200.0));leilao.propoe(new Lance(joao, 300.0));leilao.propoe(new Lance(maria, 400.0));

leiloeiro.avalia(leilao);

List<Lance> maiores = leiloeiro.getTresMaiores();assertEquals(3, maiores.size());

assertThat(maiores.size(), equalTo(3));

assertEquals(400.0, maiores.get(0).getValor(), 0.00001);assertEquals(300.0, maiores.get(1).getValor(), 0.00001);assertEquals(200.0, maiores.get(2).getValor(), 0.00001);

}

Resultado@Testpublic void deveDevolverTodosLancesCasoNaoHajaNoMinimo3() {

Leilao leilao = new Leilao("Playstation 3 Novo");leilao.propoe(new Lance(joao, 300.0));leilao.propoe(new Lance(maria, 400.0));

leiloeiro.avalia(leilao);

List<Lance> maiores = leiloeiro.getTresMaiores();assertEquals(3, maiores.size());

assertThat(maiores.size(), equalTo(2));

assertEquals(400.0, maiores.get(0).getValor(), 0.00001);assertEquals(300.0, maiores.get(1).getValor(), 0.00001);

}

Resultado@Testpublic void deveDevolverTodosLancesCasoNaoHajamLances() {

Leilao leilao = new Leilao("Playstation 3 Novo");

leiloeiro.avalia(leilao);

List<Lance> maiores = leiloeiro.getTresMaiores();assertEquals(0, maiores.size());assertThat(maiores.size(), equalTo(0));

}

Produçãopublic List<Lance> getTresMaiores() {

List<Lance> maiores;maiores = new ArrayList<Lance>(leilao.getLances());Collections.sort(maiores, new Comparator<Lance>() {

public int compare(Lance o1, Lance o2) {if(o1.getValor() < o2.getValor()) return 1;if(o1.getValor() > o2.getValor()) return -1;return 0;

}});maiores = maiores.subList(0, 3);// maiores = maiores.subList(0, maiores.size() > 3

? 3 : maiores.size());return maiores;

}

ExercícioCrie um Leilao e proponha Lance com valores randômicos, como por exemplo, 200, 450, 120, 700, 630, 230. Ao final, verifique que o menor é 120 e o maior é 700.

Resultado@Testpublic void deveEntenderLeilaoComLancesEmOrdemRandomica() {

Usuario joao = new Usuario("Joao");Usuario maria = new Usuario("Joao");Leilao leilao = new Leilao("Playstation 3 Novo");

leilao.propoe(new Lance(joao,200.0));leilao.propoe(new Lance(maria,450.0));leilao.propoe(new Lance(joao,120.0));leilao.propoe(new Lance(maria,700.0));leilao.propoe(new Lance(joao,630.0));leilao.propoe(new Lance(maria,230.0));

Avaliador leiloeiro = new Avaliador();leiloeiro.avalia(leilao);

assertEquals(700.0, leiloeiro.getMaiorLance(), 0.0001);assertEquals(120.0, leiloeiro.getMenorLance(), 0.0001);

}

Exercícioclass MatematicaMaluca {

public int contaMaluca(int numero) {if(numero > 30) return numero * 4;else if(numero > 10) return numero * 3;else return numero * 2;

}}

Resultadoclass MatematicaMalucaTest {

@Testpublic void deveMultiplicarNumerosMaioresQue30() {

MatematicaMaluca matematica = new MatematicaMaluca();assertEquals(50*4, matematica.contaMaluca(50));

}

@Testpublic void deveMultiplicarNumerosMaioresQue10EMenoresQue30() {

MatematicaMaluca matematica = new MatematicaMaluca();assertEquals(20*3, matematica.contaMaluca(20));

}

@Testpublic void deveMultiplicarNumerosMenoresQue10() {

MatematicaMaluca matematica = new MatematicaMaluca();assertEquals(5*2, matematica.contaMaluca(5));

}}

Exercícioclass FiltroDeLances {

public List<Lance> filtra(List<Lance> lances) {ArrayList<Lance> resultado = new ArrayList<Lance>();

for(Lance lance : lances) {if(lance.getValor() > 1000 && lance.getValor() < 3000)

resultado.add(lance);else if(lance.getValor() > 500 && lance.getValor() < 700)

resultado.add(lance);else if(lance.getValor() > 5000)

resultado.add(lance);}return resultado;

}}

Resultadoclass FiltroDeLancesTest {

@Testpublic void deveSelecionarLancesEntre1000E3000() {

Usuario joao = new Usuario("Joao");

FiltroDeLances filtro = new FiltroDeLances();List<Lance> resultado = filtro.filtra(Arrays.asList(

new Lance(joao,2000),new Lance(joao,1000),new Lance(joao,3000),new Lance(joao, 800)));

assertEquals(1, resultado.size());assertEquals(2000, resultado.get(0).getValor(), 0.00001);

}

Resultado@Testpublic void deveSelecionarLancesEntre500E700() {

Usuario joao = new Usuario("Joao");

FiltroDeLances filtro = new FiltroDeLances();List<Lance> resultado = filtro.filtra(Arrays.asList(

new Lance(joao,600),new Lance(joao,500),new Lance(joao,700),new Lance(joao, 800)));

assertEquals(1, resultado.size());assertEquals(600, resultado.get(0).getValor(), 0.00001);

}}

Resultados@Testpublic void deveSelecionarLancesMaioresQue5000() {

Usuario joao = new Usuario("Joao");

FiltroDeLances filtro = new FiltroDeLances();List<Lance> resultado = filtro.filtra(Arrays.asList(

new Lance(joao, 10000),new Lance(joao, 800)));

assertEquals(1, resultado.size());assertEquals(10000, resultado.get(0).getValor(), 0.00001);

}

Resultados@Testpublic void deveEliminarMenoresQue500() {

Usuario joao = new Usuario("Joao");

FiltroDeLances filtro = new FiltroDeLances();List<Lance> resultado = filtro.filtra(Arrays.asList(

new Lance(joao, 400),new Lance(joao, 300)));

assertEquals(0, resultado.size());}

Resultados@Testpublic void deveEliminarEntre3000E5000() {

Usuario joao = new Usuario("Joao");

FiltroDeLances filtro = new FiltroDeLances();List<Lance> resultado = filtro.filtra(Arrays.asList(

new Lance(joao, 4000),new Lance(joao, 3500)));

assertEquals(0, resultado.size());}

ExercícioTestar a classe Leilao : LeilaoTest

Testar um Leilão que receba apenas um lance

Resultado@Testpublic void deve_receber_um_lance() {

Leilao leilao = new Leilao("MacBook Pro 15");assertEquals(0, leilao.getLances().size());

leilao.propoe(new Lance(new Usuario("Steve Jobs"), 2000));

assertEquals(1, leilao.getLances().size());assertEquals(2000.0, leilao.getLances().get(0).getValor(), 0.0001);

}

ExercícioTestar leilao com vários lances

Resultado@Testpublic void deve_receber_varios_lances() {

Leilao leilao = new Leilao("MacBook Pro 15");leilao.propoe(new Lance(new Usuario("Steve Jobs"), 2000));leilao.propoe(new Lance(new Usuario("Steve Woznick"), 3000));

assertEquals(1, leilao.getLances().size());assertEquals(2000.0, leilao.getLances().get(0).getValor(), 0.0001);assertEquals(3000.0, leilao.getLances().get(1).getValor(), 0.0001);

}

ExercícioUma mesma pessoa não pode propor 2 lances em sequência

deve ignorar o segundo

Resultado@Testpublic void nao_deve_receber_um_segundo_lance_do_mesmo_usuario() {

Leilao leilao = new Leilao("MacBook Pro 15");leilao.propoe(new Lance(new Usuario("Steve Jobs"), 2000));leilao.propoe(new Lance(new Usuario("Steve Jobs"), 3000));

assertEquals(1, leilao.getLances().size());assertEquals(2000.0, leilao.getLances().get(0).getValor(), 0.0001);

}

Criar metodo equalsno Eclipse na classe UsuarioControl-3generate hashcode and equals

Usuario equals @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Usuario other = (Usuario) obj; if (id != other.id) return false; if (nome == null) { if (other.nome != null) return false; } else if (!nome.equals(other.nome)) return false; return true; }

produção public void propoe(Lance lance) { if(lances.isEmpty() || !ultimoLanceDado(). getUsuario().equals(lance.getUsuario())) { lances.add(lance); } }

private Lance ultimoLanceDado() { return lances.get(lances.size()-1); }

ExercícioUma pessoa não pode dar mais que cinco lances em um leilão

Resultado @Test public void naoDeveAceitarMaisDoQue5LancesDeUmMesmoUsuario() { Leilao leilao = new Leilao("Macbook Pro 15"); Usuario steveJobs = new Usuario("Steve Jobs"); Usuario billGates = new Usuario("Bill Gates"); leilao.propoe(new Lance(steveJobs, 2000)); leilao.propoe(new Lance(billGates, 3000)); leilao.propoe(new Lance(steveJobs, 4000)); leilao.propoe(new Lance(billGates, 5000)); leilao.propoe(new Lance(steveJobs, 6000)); leilao.propoe(new Lance(billGates, 7000)); leilao.propoe(new Lance(steveJobs, 8000)); leilao.propoe(new Lance(billGates, 9000)); leilao.propoe(new Lance(steveJobs, 10000)); leilao.propoe(new Lance(billGates, 11000)); // deve ser ignorado leilao.propoe(new Lance(steveJobs, 12000)); assertEquals(10, leilao.getLances().size()); int ultimo = leilao.getLances().size() - 1; Lance ultimoLance = leilao.getLances().get(ultimo); assertEquals(11000.0, ultimoLance.getValor(), 0.00001); }

produçãopublic void propoe(Lance lance) {

int total = 0; for(Lance l : lances) { if(l.getUsuario().equals(lance.getUsuario())) total++; }

if(lances.isEmpty() || (!ultimoLanceDado().getUsuario().equals(lance.getUsuario()) && total < 5)) { lances.add(lance); } }

produção public void propoe(Lance lance) { if(lances.isEmpty() || ( !ultimoLanceDado().getUsuario().equals(lance.getUsuario()) && qtdDelancesDo(lance.getUsuario()) < 5)) { lances.add(lance); } }

private int qtdDelancesDo(Usuario usuario) { int total = 0; for(Lance lance : lances) { if(lance.getUsuario().equals(usuario)) total++; } return total; }

produção public void propoe(Lance lance) { if(lances.isEmpty() || podeDarLance(lance.getUsuario())) { lances.add(lance); } }

private boolean podeDarLance(Usuario usuario) { return !ultimoLanceDado().getUsuario().equals(usuario) && qtdDelancesDo(usuario) < 5; }

ExercícioConstruir o método criadorDeLeilao: (Test Data Builder)

@Test public void deveEncontrarOsTresMaioresLances() { Leilao leilao = new CriadorDeLeilao().para("Playstation 3 Novo") .lance(joao, 100.0) .lance(maria, 200.0) .lance(joao, 300.0) .lance(maria, 400.0) .constroi(); leiloeiro.avalia(leilao);

List<Lance> maiores = leiloeiro.getTresMaiores(); assertEquals(3, maiores.size()); assertEquals(400.0, maiores.get(0).getValor(), 0.00001); assertEquals(300.0, maiores.get(1).getValor(), 0.00001); assertEquals(200.0, maiores.get(2).getValor(), 0.00001); }}

Resultadopublic class CriadorDeLeilao {

private Leilao leilao;

public CriadorDeLeilao() { }

public CriadorDeLeilao para(String descricao) { this.leilao = new Leilao(descricao); return this; }

public CriadorDeLeilao lance(Usuario usuario, double valor) { leilao.propoe(new Lance(usuario, valor)); return this; }

public Leilao constroi() { return leilao; }}

ExercícioEnviar uma exceção ao avaliar um leilão com zero lances

public void avalia(Leilao leilao) { // lancando a excecao if(leilao.getLances().size() ==0) throw new RuntimeException("Não é possível avaliar um leilão sem lances");

Para tratar pode-se usar try catch

Resultado

@Testpublic void naoDeveAvaliarLeiloesSemNenhumLanceDado() { try { Leilao leilao = new CriadorDeLeilao() .para("Playstation 3 Novo") .constroi();

leiloeiro.avalia(leilao); Assert.fail(); } catch(RuntimeException e) { // deu certo! }}

Resultado

Pode-se usar a anotaço @Test(expected= exceção.class)

@Test(expected=RuntimeException.class)public void naoDeveAvaliarLeiloesSemNenhumLanceDado() { Leilao leilao = new CriadorDeLeilao() .para("Playstation 3 Novo") .constroi();

leiloeiro.avalia(leilao);}

ExercícioassertThat (calculado , matcher(expectativa)

class AvaliadorTest {

@Test public void deveEntenderLancesEmOrdemCrescente() {

Leilao leilao = new CriadorDeLeilao() .para("Playstation 3 Novo") .lance(joao, 250) .lance(jose, 300) .lance(maria, 400) .constroi();

leiloeiro.avalia(leilao);

assertThat(leiloeiro.getMenorLance(), equalTo(250.0)); assertEquals(400.0, leiloeiro.getMaiorLance(), 0.00001); }}

ExercícioHamcrest

http://code.google.com/p/hamcrest/downloads/detail?name=hamcrest-all-1.3.0RC1.jar

http://code.google.com/p/hamcrest/wiki/Tutorial

Exercício @Test public void deveEncontrarOsTresMaioresLances() { Leilao leilao = new CriadorDeLeilao() .para("Playstation 3 Novo") .lance(joao, 100) .lance(maria, 200) .lance(joao, 300) .lance(maria, 400) .constroi();

leiloeiro.avalia(leilao);

List<Lance> maiores = leiloeiro.getTresMaiores(); assertEquals(3, maiores.size());

assertEquals(400.0, maiores.get(0).getValor(), 0.00001); assertEquals(300.0, maiores.get(1).getValor(), 0.00001); assertEquals(200.0, maiores.get(2).getValor(), 0.00001); }

ExercícioassertThat(maiores, hasItems( new Lance(maria, 400), new Lance(joao, 300), new Lance(maria, 200) ));

Exercício

Resultado

Exercício

Resultado

Exercício

Resultado

Exercício

Resultado

Exercício

Resultado

Estados