Introducing
Tests of any kind need to test something. This example is testing nothing.
You can test whatever you want in the test, you can access database without problems. Of course it is not ideal because tests should ideally run very fast and not have many dependencies.
To make tests meaningful and effective you need a design very good application before anything else. My experience shows that you can only do tests that are worth anything when the programmer can already produce good code. Not that you can’t try, but flawed codes indicate that the programmer hasn’t reached the level of understanding everything that’s needed to produce tests. One of those flaws is not separating responsibilities well. Another is to understand how a language works, how the computer works, the complete understanding of basic mathematics.
So come on.
Your example
Methods should not mix responsibilities. If it is a validator it should not send messages to the user, it is the responsibility of something else, in another class. A validator should only test conditions and say whether it is right or not.
I imagine the method listaTodos()
access the database. To facilitate the test you need to have a way to call a method that simulates the result in a controlled way, quickly and without dependencies. One of the ways is to use dependency injection. Another is to completely replace the object class categoriaDao
for a version that does not access the database but generates an easily testable result.
There are specific techniques to replace the normal behaviour of a method.
If you choose DI (dependency Injection) is very easy, just receive the object by a parameter. I particularly do not like to change a method just to test, I prefer a more global solution. But it’s an option, so you’d have to rethink all the code of all the classes to be suitable for the test.
Giving an improved in other points the method would look like this:
public boolean validaEntradaDeDadosPadrao() {
for (Categoria c : categoriaDao.listaTodos()) {
if (c.getNomeCategoria().equals("Financeiro")) {
return false;
}
}
return true;
}
I preferred not to change the method name because I do not know the specification of the problem, but it seems wrong.
Then we can do the test (I do not say it is the best way, but a possibility of improvement). I will post here an approximate way:
class Dao {
public List<Categoria> listaTodos() {
list<Categoria> lista = new List<>();
lista.Add(new Categoria("Financeiro")); //claro que é mais complexo que isto
lista.Add(new Categoria("OutraCategoria"));
return lista; //nenhum banco de dados é acessado e provê os dados necessários
}
}
This class would be the substitute for the original that accesses the database. Of course it would be more complex than this.
Here you would have to create infrastructure to test in different ways, provoke different situations, create situation that generates a result or other, that can force an error, make the code run in all possible ways.
@Test
public void testValidaEntradaDeDadosPadrao() {
Assert.assertEquals(validaEntradaDeDadosPadrao(), true);
}
I put in the Github for future reference.
Here you are testing something useful.
Well, that’s about it. The intention is not to produce the ready-to-use test, because the question data does not allow it, but to give basic information that the test is done differently.
First, you really need
System.out.println()
? Me all validation should not send messages. Second: the test does nothing useful and does not test the validation method.– Maniero
Did any of the answers below solve your problem? Do you think you can accept one of them? Check out the [tour] how to do this, if you still don’t know how to do it. This helps the community by identifying the best solution for you. You can only accept one of them, but you can vote for any question or answer you find useful on the entire site.
– Maniero