Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I write tests for class A if it's covered from class B

I'd like to get some opinion about testing methodology.

Lets assume we have class A and B. Class B uses functionality of class A. The B class is fully tested and thus some test coverage is also applied indirectly for class A.

Should I write full tests directly for class A? Or should I test only not tested A class functionality?

I am asking because maybe in the future there will be possibility that the B class will be removed or modified in the way that it might not use the same functionality from A class so it might leave some methods untested. What would you do?

like image 629
tobi Avatar asked Jan 31 '14 14:01

tobi


4 Answers

CLASSES != UNITS

If you practice a good TDD, you will understand easily what is behind.


IMO, you should test B's behavior without based on the fact that A would already be tested.

Actually, there are three cases:

A and B BELONGING TO THE SAME LAYER:

  • If A is created through refactor cycle (extract class) of B (happens often while practicing a good TDD), then A should TOTALLY be left untested! No need to test it at all!
    Indeed, structure of code (in this case, separation of classes/SRP) should be independent of Unit concept; B and A in this case belonging to the same unit.

  • If A existed BEFORE B, B should not be based on this fact, and B's whole behavior should be tested.

A and B NOT BELONGING TO THE SAME LAYER (distinct boundaries for instance):

  • If B is a GUI class, and A a business class, then A should be doubled/mocked when testing B, and also A should have a full test dedicated for it.
    Indeed, domain architecture should not be mingled with behavior/feature notion.

To understand why, read this recent article of Uncle Bob dealing with this concept:

http://blog.8thlight.com/uncle-bob/2014/01/27/TheChickenOrTheRoad.html?utm_source=hootsuite&utm_campaign=hootsuite

Excerpt of it:

It is a common misconception that the design of the tests must mirror the design of the production code. TDD does not require, as the Author suggests, "that every unit in your system is paired with a well-designed [...] unit test." Indeed, that's one of the reasons that many of us have stopped calling them "unit" tests.

Note: TDD doesn't care about "future", in the contrary, it helps you to write as much code as you need, no more. Therefore you should not worry about this:

in the future there will be possibility that the B class will be removed or modified

If you wrote good tests (I prefer the word "specs"), such removal would be detected immediately.

like image 173
Mik378 Avatar answered Nov 02 '22 04:11

Mik378


Yes, you should fully test A.

  1. B might change at some point down the road, so just because it uses A now doesn't mean that it always will.

  2. B may not use all of the functionality of A which means that you're not testing all of your code.

like image 41
Justin Niessner Avatar answered Nov 02 '22 06:11

Justin Niessner


Definately write full tests for class A. You kind of answered your own question here:

(...)maybe in the future there will be possibility that the B class will be removed or modified in the way that it might not use the same functionality from A class so it might leave some methods untested.

like image 33
Reinstate Monica Avatar answered Nov 02 '22 05:11

Reinstate Monica


The general thought behind unittesting is that each unit is comprised of a Unit of Work. This can be as small as a method or as big as several methods working together.

You have already covered the scenario where B is dependent on A but from your story we can assume A will also be used separately. Therefore A should also be tested since it is a separate Unit of Work.

like image 29
Jeroen Vannevel Avatar answered Nov 02 '22 06:11

Jeroen Vannevel