Java – On the effectiveness of unit testing

javatestingunit testing

How effective are unit tests in reality?

I am under the impression that at some point unit tests turn into tests that test the dependency between the object under test and another object. Sure, one can always abstract dependencies using interfaces, but what happens when even the interfaces should be changed? What if the unit under test no longer relies on those dependencies?

If our tests fail because of dependency issues, does it mean they are too coupled to our code? Also, do we have to change them every time when we change the dependencies?
If it happens quite often, is this a sign that our design is wrong?

I tended to believe that unit tests are an effective way to test ensure robustness, but if they are too coupled to the dependencies that our objects have with other objects (be they expressed as interfaces), it simply leads to more time wasted in fixing those tests to pass the new design. Am I wrong?

The thing is, I am perfectly aware of the existence of mocking frameworks, and so on. This is not the problem. The problem is what happens when you change your method's implementation and it simply doesn't call the mock anymore, and you start seeing a bunch of red lights in your test stack, because your mocks aren't called the way the way they should? Unit or Integration test, something should be done here, right?

If I start writing different mock methods for every test condition I like, what happens if I decide to change the signature of the class I've mocked? All my tests go to the trash bin, right? Is this normal, can it be avoided? Is it a design problem?

Best Answer

The person that told you testing dependencies is integration testing rather than unit testing is indeed correct. Unit testing normally consists of creating mock objects of any dependencies and testing a single Class as a single "unit". You are only testing that it calls the correct methods on its dependencies and returns the correct things IF the dependencies return the correct things. This is one of the good reasons for using interfaces for your Classes as you can easily create a mock from an interface using for example EasyMock.

Unit tests are very useful as long as they are done right, but I do believe that some people take them too far. You don't need 100% code coverage, just make sure anything that isn't obviously correct is reasonably tested. I recommend adding system tests as well for any complicated system - these tests won't mock anything, they just test the system as a whole.

You may want to read some of the answers at https://stackoverflow.com/questions/16860/getting-started-with-unit-testing for getting the most out of your unit testing.

Related Topic