Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I need to write unit tests for methods of services without logic?

Tags:

unit-testing

Do I need test service methods like this?

@Transactional
@Override
public Charge saveAndFlush(Charge charge) {
    return chargesRepository.saveAndFlush(charge);
}

In principle, there is nothing to test. Therefore, the question arose - to write a test anyway, because in the future it is possible that someone will add logic here. Or let him write the one who will add logic (if at all).

like image 507
ip696 Avatar asked Dec 10 '18 12:12

ip696


People also ask

Does every method need a unit test?

The answer to the more general question is yes, you should unit test everything you can. Doing so creates a legacy for later so changes down the road can be done with peace of mind. It ensures that your code works as expected. It also documents the intended usage of the interfaces.

Should unit tests contain logic?

Unit tests should contain as little logic as possible For each test, it's important to be as clear as possible about what is being tested. This both helps to make sure the tests do what we expect as well as to help the tests serve as documentation for how the code should be called and should work.

Is it mandatory to write test cases for every logic?

No, you do not have to write tests for every method.

Are unit tests always necessary?

Unit tests are also especially useful when it comes to refactoring or re-writing a piece a code. If you have good unit tests coverage, you can refactor with confidence. Without unit tests, it is often hard to ensure the you didn't break anything.


4 Answers

Generally speaking you focus your unit tests on code that returns a value by performing some computation or processing.
You could unit test a method that does not return any value to ensure it's going through without running exceptions while executing all the possible paths.
In the case above I believe you should not write a test for it. There's really no logic in that method and you'd be unit testing the spring framework. There's no need for that as the spring framework already has plenty of unit tests.
Do notice unit tests are supposed to run fast and must work standalone, that is, a unit test cannot depend on a database or network connection. So that's another reason not to unit test it as you would depend on a database to verify the code worked.

like image 106
fpezzini Avatar answered Nov 15 '22 09:11

fpezzini


there is nothing to test

Well, there is. Because doing no tests can not distinguish between the correct implementation and the following faulty "implementations":

{
   return null;
}

{
   return chargesRepository.saveAndFlush(null);
}

{
   return chargesRepository.saveAndFlush(new Charge());
}

{
   return chargesRepository.someOtherMethod(charge);
}

But you are right to think there is very little to test. Assuming the class of chargesRepository is already properly tested, you only need one or two unit tests to show that the method correctly delegates to the chargesRepository.

like image 31
Raedwald Avatar answered Nov 15 '22 07:11

Raedwald


I found this answer to a similar question:

Kent Beck's rule of thumb:

Test everything that could possibly break. Of course, that is subjective to some extent. To me, trivial getters/setters and one-liners like yours above usually aren't worth it. But then again, I spend most of my time writing unit tests for legacy code, only dreaming about a nice greenfield TDD project... On such projects, the rules are different. With legacy code, the main aim is to cover as much ground with as little effort as possible, so unit tests tend to be higher level and more complex, more like integration tests if one is pedantic about terminology. And when you are struggling to get overall code coverage up from 0%, or just managed to bump it over 25%, unit testing getters and setters is the least of your worries.

OTOH in a greenfield TDD project, it may be more matter-of-fact to write tests even for such methods. Especially as you have already written the test before you get the chance of starting to wonder "is this one line worth a dedicated test?". And at least these tests are trivial to write and fast to run, so it's not a big deal either way.

like image 25
pwain Avatar answered Nov 15 '22 09:11

pwain


The key reason for this method to exist is the transactional annotation and the side effect on the charges repository. That's also the most likely/only thing to not work as expected. That's something you find out with an integration test. Unit testing this is completely pointless because you'd mock the storage and ignore the annotations. So, you are basically unit testing that a random call on a mock works. Which, surprisingly, tends to mostly work as you'd hope.

So, make sure you cover all relevant repository methods with only a few good integration/scenario tests (i.e. don't write one per method but combine them into realistic scenarios). Focus unit tests on things with algorithmic complexity that have more than 1 line of code or any kind of branches. That way you can mock your DAO class when unit testing your service classes with actual business logic may have real bugs because you already know the DAOs have the desired side effects from integration testing.

like image 31
Jilles van Gurp Avatar answered Nov 15 '22 08:11

Jilles van Gurp