Olá,
Eu preciso testar um método, mas ele tem retorno void, como faço isso? Tentei dividir ele em dois métodos, um com algum retorno, e outro que imprimisse mas não consegui.
É uma classe Pizza, que adiciona os ingredientes em uma lista, e esse método contabiliza e imprime todos os ingredientes.
public void contaIngredientes() {
for (String ingrediente : listaIngredientes) {
int frequency = Collections.frequency(listaIngredientes, ingrediente);
System.out.println(ingrediente + ": " + frequency);
}
}
Quando existe mais de um ingrediente, o método contabiliza ele corretamente, mas imprime duas vezes o nome do ingrediente conforme a ordem que eles aparecem na lista. Vocês poderiam me ajudar a consertar isso também?
Como você está tentando testar esse método? Já tem algo escrito?
Testar métodos void
é realmente algo mais complicado, pois depende do que o método tem que fazer. Nesse seu caso, ele vai contar os ingredientes. O bom é que o teste vai ajudar a identificar possíveis falhas no código escrito.
Nesse seu caso, seria mais fácil testar esse método se ele retornasse o total de ingredientes, isso iria fazer com que esse método fizesse mais sentido do que apenas imprimir algum valor no console com System.out.println
.
Vc pode postar a classe completa para podermos entender melhor o objetivo dela? Vendo só esse método, a recomendação que faço é fazer com que ele retorne o total mesmo.
A classe completa é essa:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Pizza {
static List<String> listaIngredientes = new ArrayList<>();
double valorPizza = 0;
static int quantidadeEstatica = 0;
int quantidade = 0;
public void adicionaIngrediente(String ingrediente) {
listaIngredientes.add(ingrediente);
quantidade++;
contabilizaIngredientes();
}
public double getPreco() {
if (quantidade <= 2) {
valorPizza = 15;
return valorPizza;
}
if(quantidade>=3 && quantidade<=5) {
valorPizza = 20;
return valorPizza;
}
else {
valorPizza = 23;
return valorPizza;
}
}
public static void contabilizaIngredientes () {
quantidadeEstatica++;
}
public void contaIngredientes () {
for (String ingrediente : listaIngredientes) {
int frequency = Collections.frequency(listaIngredientes, ingrediente);
System.out.println(ingrediente + ": " + frequency);
}
}
public static void zeraIngredientes() {
quantidadeEstatica = 0;
}
Eu tentei fazer o método retornar o frequency, em vez de imprimir ele na tela, só que daí ele só retorna o valor do primeiro item da lista. Aí eu tentei fazer ele retornar o frequency como uma lista, mas não consegui fazer isso, o código só dava erro. 
Pelo que estou entendendo, o método contaIngredientes
deve contar o total por tipo de ingrediente dentro da lista de ingredientes. Se for isso mesmo, o retorno desse método seja um Map, pois vc terá um total para cada ingrediente que é usado na lista de ingredientes. Ex.:
List<String> ingredientes = new ArrayList<>();
ingredientes.add("ingredienteA");
ingredientes.add("ingredienteA");
ingredientes.add("ingredienteB");
ingredientes.add("ingredienteB");
ingredientes.add("ingredienteB");
ingredientes.add("ingredienteC");
System.out.println(Collections.frequency(ingredientes, "ingredienteA")); // 2
System.out.println(Collections.frequency(ingredientes, "ingredienteB")); // 3
System.out.println(Collections.frequency(ingredientes, "ingredienteC")); // 1
É isso mesmo que esse método contaIngredientes
tem que fazer?
É isso mesmo que o método tem que fazer.
A sua sugestão é que ele retorne um Map? Daí esse Map daria para testar?
Você pode me mostrar como eu faço isso, por favor?
Classe Pizza
com algumas modificações:
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Pizza {
private static final List<String> ingredientes = new ArrayList<>();
private double valorPizza = 0;
public void adicionaIngrediente(String ingrediente) {
ingredientes.add(ingrediente);
}
public double getPreco() {
if (getTotalIngredientes() <= 2) {
valorPizza = 15;
return valorPizza;
}
if (getTotalIngredientes() >= 3 && getTotalIngredientes() <= 5) {
valorPizza = 20;
return valorPizza;
} else {
valorPizza = 23;
return valorPizza;
}
}
public Map<String, Integer> contarIngredientes() {
Map<String, Integer> totalPorIngredientes = new HashMap<String, Integer>();
for (String ingrediente : ingredientes) {
int frequency = Collections.frequency(ingredientes, ingrediente);
totalPorIngredientes.put(ingrediente, frequency);
}
return totalPorIngredientes;
}
public Integer getTotalIngredientes() {
return ingredientes.size();
}
public void zerarIngredientes() {
ingredientes.clear();
}
}
Classe de Teste
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class PizzaTest {
private Pizza fixture;
@BeforeEach
void setup() {
fixture = new Pizza();
}
@Test
public void devePossuirAQuantidadeCorretaDeIngredientes() {
// Arrange
fixture.adicionaIngrediente("ingredienteA");
fixture.adicionaIngrediente("ingredienteA");
fixture.adicionaIngrediente("ingredienteB");
fixture.adicionaIngrediente("ingredienteB");
fixture.adicionaIngrediente("ingredienteB");
fixture.adicionaIngrediente("ingredienteC");
// Act
Map<String, Integer> actual = fixture.contarIngredientes();
// Assert
Assertions.assertEquals(2, actual.get("ingredienteA"));
Assertions.assertEquals(3, actual.get("ingredienteB"));
Assertions.assertEquals(1, actual.get("ingredienteC"));
}
}
Caraca, Lucas! Valeu mesmo!
Estou fazendo um curso de Java, mas o curso é muito ruim, didática péssima, não ensina nada você a fazer as coisas e já pede pra entregar o exercício, aí estou perdidona. Mas, brigadão.
Aqui no GUJ tem muita gente que entende bastante de testes, sem falar que teste é algo fundamental para um bom desenvolvimento e, em muitas vezes, deixado de lado. Aqui no meu trabalho a galera força muito a questão de testes (seja unitário, integração ou até mesmo funcional, dependendo do caso). Mas teste unitário sempre é bom fazer.
Esse seu exemplo é muito para fazer uns testes bacanas. Qualquer dúvida, soh falar.
Qual curso vc está fazendo?
obs.: Nessa classe de teste, usei o JUnit na versão 5 ok. Se vc rodar ele com a versão 4 do JUnit, não vai funcionar.
Eu estou fazendo um que é o primeiro módulo de uma especialização do ITA, chama Orientação a Objetos com Java, fica na plataforma Coursera. Mas não gostei.
Você conhece algum curso bom?
Eu trabalho com suporte hoje, mas em fevereiro vou começar a trabalhar com desenvolvimento, aí tava querendo ir praticando bastante antes de entrar.
Uns cursos bem avaliados que vejo muito a galera comentar são esses:
Bacana, também comecei como suporte antes de ir para área de desenvolvimento.
Se vc for trabalhar com java, recomendo que dê uma olhada em Spring, que é amplamente utilizado hoje em dia).
Valeu pelas dicas, Lucas!
Marque depois a resposta que te ajudou como solução. Vlw!