Aniche Mauricio - Test-Driven Development: Teste e Design no Mundo Real com .NET стр 17.

Шрифт
Фон

{

return 0;

}

}

Ainda não há uma repetição de código grande a ser eliminada, então podemos

ir para o próximo teste, que é o caso do carrinho conter apenas um produto. O teste:

51

5.1. O Problema do Carrinho de Compras

Casa do Código

[Test]

public void DeveRetornarValorDoItemSeCarrinhoCom1Elemento()

{

CarrinhoDeCompras carrinho = new CarrinhoDeCompras();

carrinho.Adiciona(new Item("Geladeira", 1, 900.0));

MaiorPreco algoritmo = new MaiorPreco();

double valor = algoritmo.Encontra(carrinho);

Assert.AreEqual(900.0, valor, 0.0001);

}

Para fazer esse teste passar, precisaremos escrever um pouco mais de código. Mas

não há muitas dúvidas sobre o algoritmo nesse momento: se o carrinho estiver vazio,

retorna 0. Caso contrário, retorna o valor do primeiro elemento desse carrinho:

public double Encontra(CarrinhoDeCompras carrinho)

{

if(carrinho.Itens.Count == 0) return 0;

return carrinho.Itens[0].ValorTotal;

}

Por fim, o cenário que resta: é necessário encontrar o item de maior valor caso o

carrinho contenha muitos itens:

[Test]

public void DeveRetornarMaiorValorSeCarrinhoContemMuitosElementos()

{

CarrinhoDeCompras carrinho = new CarrinhoDeCompras();

carrinho.Adiciona(new Item("Geladeira", 1, 900.0));

carrinho.Adiciona(new Item("Fogão", 1, 1500.0));

carrinho.Adiciona(new Item("Máquina de Lavar", 1, 750.0));

MaiorPreco algoritmo = new MaiorPreco();

double valor = algoritmo.Encontra(carrinho);

Assert.AreEqual(1500.0, valor, 0.0001);

}

52

Casa do Código

Capítulo 5. TDD e Design de Classes

Vamos à implementação. É necessário navegar pelos itens da coleção, procu-

rando pelo item de maior valor total. Para armazenar esse maior valor é necessário

um atributo da classe, batizado de maior":

public double Encontra(CarrinhoDeCompras carrinho)

{

if(carrinho.Itens.Count == 0) return 0;

double maior = carrinho.Itens[0].ValorTotal;

foreach(var item in carrinho.Itens) {

if(maior < item.ValorTotal) {

maior = item.ValorTotal;

}

}

return maior;

}

Com todos os testes passando, é hora de avaliá-los. Observe, por exemplo, o

último teste que escrevemos. Veja que o teste instancia a classe MaiorPreco, passa

para ela um carrinho e verifica o retorno desse método. Repare que todo o cená-

rio montado foi em cima da classe CarrinhoDeCompras; não fizemos nada na classe

MaiorPreco.

Isso pode ser um mau sinal. Sabemos que uma das vantagens da orientação a

objetos em relação a códigos mais procedurais é justamente a capacidade de unir

dados e comportamentos. A classe MaiorPreco parece estranha, já que não houve

necessidade de setar atributos ou qualquer outro dado nela.

Sabendo desse possível problema na classe, vamos ver seu código. Repare que o

método encontra() faz uso do carrinho praticamente o tempo todo, e não faz uso

de nada específico da sua própria classe.

A pergunta é: por que criamos essa classe? Por que o método encontra() não

está dentro da própria classe CarrinhoDeCompras ?

Vamos fazer essa mudança.

Se levarmos toda a lógica do método

encontra() para um método chamado, por exemplo, maiorValor() dentro do

CarrinhoDeCompras, a classe ficará assim:

public double MaiorValor()

{

if(Itens.Count == 0) return 0;

53

5.1. O Problema do Carrinho de Compras

Casa do Código

double maior = Itens[0].ValorTotal;

foreach(var item in Itens) {

if(maior < item.ValorTotal) {

maior

= item.ValorTotal;

}

}

return maior;

}

Já os testes ficarão assim:

[TestFixture]

public class CarrinhoDeComprasTest

{

[Test]

public void DeveRetornarZeroSeCarrinhoVazio()

{

CarrinhoDeCompras carrinho = new CarrinhoDeCompras();

Assert.AreEqual(0.0, carrinho.MaiorValor(), 0.0001);

}

[Test]

public void DeveRetornarValorDoItemSeCarrinhoCom1Elemento()

{

CarrinhoDeCompras carrinho = new CarrinhoDeCompras();

carrinho.Adiciona(new Item("Geladeira", 1, 900.0));

Assert.AreEqual(900.0, carrinho.MaiorValor(), 0.0001);

}

[Test]

public void DeveRetornarMaiorValorSeCarrinhoContemMuitosElementos()

{

CarrinhoDeCompras carrinho = new CarrinhoDeCompras();

carrinho.Adiciona(new Item("Geladeira", 1, 900.0));

carrinho.Adiciona(new Item("Fogão", 1, 1500.0));

carrinho.Adiciona(new Item("Máquina de Lavar", 1, 750.0));

54

Casa do Código

Capítulo 5. TDD e Design de Classes

Assert.AreEqual(1500.0, carrinho.MaiorValor(), 0.0001);

}

}

Veja agora que nosso teste está muito mais claro e elegante.

Os testes do

CarrinhoDeCompras instanciam um carrinho, montam o cenário desejado e invo-

cam um método do próprio carrinho. Agora o código dentro do teste parece melhor

e mais orientado a objetos. O comportamento está no lugar esperado. É justamente

isso que se espera de um código de qualidade.

Antes de continuarmos, vamos refletir um pouco sobre como descartamos a pri-

meira solução e chegamos à solução que melhor resolveu o problema.

5.2

Testes que influenciam no design de classes

O que nos fez optar pelo segundo caminho ao invés do primeiro? Em que momento

mudamos o rumo da implementação? Releia o texto acima. Repare que o que nos

Ваша оценка очень важна

0
Шрифт
Фон

Помогите Вашим друзьям узнать о библиотеке