JUnit, como fazer os testes? Isso é realmente util?

Estava lendo sobre JUnit e a ideia de criar os testes, mas não entendi algumas coisas, como por exemplo:

1-Quando tenho um metodo void como é que eu vou testar pelo JUnit?

2- Quando crio um método eu já não estou testando ele?
Afínal ninguém vai colocar métodos que não funcionem em suas classes.

3- Depois de ter criado o método-teste, quando ele vai ser usado novamente? crio ele e ele fica solto por ai?

Estou começando com esse JUnit e nao entendi a ideia dele.

Não é que você não entendeu JUnit, você não entendeu a ideia do TDD.

Fala velho :slight_smile:

Sou iniciante mas a idéia do JUnit é COMPROVAR que o seu trabalho esta sendo bem feito e as suas classes estão funcionando bem…

E mas uma prova para o empregador (Cliente) de que o código o sistema que ele esta pegando esta funcionando bem todo o desenvolvedor deveria testar os seus códigos + realmente não da tempo xD

Abraço.

Dei uma pesquisada rápida aqui mas de-repente te ajuda

http://javafree.uol.com.br/wiki/JUnit

http://junit.wikidot.com/

Abraço.

Me falaram um pouco sobre test driven development e, me corrijam se eu estiver errado, a ideia dela é testar os metodos enquanto os criamos mas isso acho que já é implicito, afinal como vou usar um metodo que nao funciona?

Quando se tem poucos métodos, é fácil verificar o funcionamento. Mas em um sistema com centenas ou milhares de classes, uma alteração simples pode gerar consequências enormes. Com testes automatizados, os problemas podem ser rastreados rapidamente, reduzindo a quantidade de bugs no produto final.

1 - Imagine uma classe de salvar pessoas:

[code]class Pessoa {
// Um monte de atributos
}

// Fachada, Servico, Business Object, etc, interface que gerenciará a pessoa
interface PessoaXYZ {
void salvar(Pessoa p);
}

class PessoaTest extends TestCase {
void testSalvarNulo() {
PessoaXYZ xyz = …;
xyz.salvar(null); // Aqui vc espera um erro, tem umas anotações/métodos para tratar essas exceções como esperadas
}
void testSalvarOK() {

Pessoa pessoa = new Pessoa(…);
xyz.salvar(pessoa); // Aqui vc espera que não de erro
}
void testUpdateErro() {
// Aqui vc forca um update errado, passando null ou uma pessoa com identificador vazio
}
[/code]}

2 - Com certeza NÃO, quem testa seu método é a classe que chama.

[code]void print(Object o) {
System.out.println(o.toString());
}

print(“OK”); // OK
print(null); // Erro, NullPointerException, o seu método deveria tratar valores null ou lançar uma exceção mais clara[/code]

3 - Ferramentas como Maven executam todos os testes e caso algum de errado a build não é criada.

[ EDIT ]
A anotação abaixo faz o JUnit tratar a exceção como resultado esperado, não gerando erro
@Test (expected=AlgumaException.class)

Tenho ainda algumas perguntas em relação ao JUnit.

desculpem fazer tantas perguntas, ja li varios artigos e achei bastante confusa a ideia.

Por exemplo, tenho a seguinte situação:

Tenho um metodo com retorno nulo e que tem um parametro que cadastra uma pessoa em um banco, salvarPessoa(Pessoa pessoa) por exemplo, e quero testa-lo, como fazer? até porque preciso da conexao entao nao poderia testa-lo individualmente.

no caso seria mais ou menos assim:

@test
public void testCadastroPessoa(){

  • 1 * salvarPessoa(Pessoa pessoa);

}

  • 1 * A)Como vou construir a pessoa sem passar parametros no testCadastroPessoa()???

       B) E como poderia funcionar esse metodo se eu nao tenho uma conexao com o banco, pois ele vai ter que cadastar em algum lugar para realizar o teste ne?
    
       C) E memso se eu tivesse a conexao, a cada teste vou passar o mesma pessoa sempre que eu for testar isso??? nao vai causar probemas no banco isso?
    

Achei confuso…

     D)Tenho que fazer um metodo forçando um erro? e se sim porque?? nao me parece util

Outro caso:

@test
public void testCadastroPessoa(){

  • 2 * assertEquals(“Minha mensagem”,salvarPessoa(Pessoa pessoa), true);

}

  • 2 * Retornar true no metodo nao vai garantir um bom teste pois ele pode retornar true e nao realizar a ação desejada.
    Como fazer um teste desses?

Então, diversos frameworks disponibilizam extensões para pode rodar testes unitários. O Spring, por exemplo, possui extensões para pode rodar seus testes inicializando um ApplicationContext, o JBoss possui projetos para testar EJBs, JSF, etc, em testes unitários.

A) Vc pode construir a pessoa manualmente, tipo new Pessoa() e depois usar os métodos set para definir os atributos ou usar um framework para criar objetos mock, como o JMock.
B) Sobre a questão da conexão, do meu ponto de vista, não deveria ser o cliente que cria uma conexão com o banco e sim sua classe responsável por gravar os dados. Nos métodos vc pode colocar umas anotações para o método rodar antes do seu teste, ai neste ponto vc poderia inicializar as configurações de sua aplicação(conexão com o banco, propriedades, etc).
C) Ai depende da situação, mas provavelmente em cada chamada passará um conjunto de dados diferente, afinal vc deseja testar seu projeto em diferentes situações.

bem sobre a questao a vc falou dar um new Pessoa() e setar os atributos, mas dessa maneira como posso ter varias pessoas diferentes pois toda vez que esse metodo for chamado vai cirar o mesmo objeto. como posso ter casos diferentes dessa maneira?

Vc pode ter vários testes em uma mesma classe, como coloquei no 1 exemplo:

[code]void testSalvarErro() {
Pessoa p = new Pessoa();
p.set…;
xyz.salvar§; // Se neste ponto não der erro algo esta errado
}

void testSalvarOK() {
Pessoa p = new Pessoa();
p.set…;
xyz.salvar§; // Se neste ponto der erro algo esta errado
}

// E por ai vai

void testExcluirOK();
void testExcluirErro();

// Ou usando mock
void testSalvarMock() {
Pessoa p = …criaMock(); // cria o mock, depende da implementação
xyz.salvar§; // Dependendo de como seu mock foi criado, vc pode esperar um erro ou não
}[/code]

Por que no teste unitário vc passa um valor e espera um determinado retorno. Por exemplo se somar 1 + 1 eu espero 2, se não vier 2 algo está errado. Da mesma forma posso somar 1 +1, esperar 3 e o método me retornar 2, nesse caso não é o método que esta errado e sim meu teste.

Vamos lá…

Independente de qualquer metodologia de desenvolvimento(TDD, BDD, etc…) o objetivo dos testes unitario é grarantir que determinada funcionalidade do seu sistema esta realmente funcionando. Como você citou, ninguem coloca metodos que não funcionem, porem como vc garante que em “n” situações o resultado será o esperado. Para grandes empresas, testes unitarios são obrigatorios, ele geram grande parte das evidencias de teste.

Não necessariamente você precisa testar metodo a metodo, e sim funcionalidades.

Seu testes deve funcionar independentemente de recursos externos, por exemplo, Banco de Dados ou qualuqe operação I/O.

Você pode garantir isso com Mocks que simulam essas informações, entaum existem algumas regras para implementar isso.

No caso de testar um metodo void como vc citou, msm ele sendo void ele executou alguma tarefa sendo assim vc pode verificar se o que ele executou resultou no esperado.

Qlq duvida poste ai…

Abraço…

Com certeza é util… serve para uma série de coisas entre elas comprovar a consistência do sistema…
não basta apenas rodar, tem que testar