Como testar um método void com JUnit?

12 respostas Resolvido
java
C

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?

12 Respostas

L

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.

C

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. :frowning:

L

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?

C

É 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?

L
Solucao aceita

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"));
    }

}
C

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.

L

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.

C

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.

L

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.

L

Se vc for trabalhar com java, recomendo que dê uma olhada em Spring, que é amplamente utilizado hoje em dia).

C

Valeu pelas dicas, Lucas!

L

Marque depois a resposta que te ajudou como solução. Vlw!

Criado 11 de novembro de 2019
Ultima resposta 12 de nov. de 2019
Respostas 12
Participantes 2