Unit testing indeed is extra work but it pays off in the long run. Here are the
advantages over integration testing :
- you get a regression suite that acts as a safety net in case of refactoring - the same can be said of integration tests, although it can be tough to say if
the test covers a piece of code.
- unit tests give an immediate feedback when modifying the code - and this
feedback can be very accurate, pointing to the method where the anomaly
is.
- those tests are cheap to run : they run very fast (a few seconds typically),
without any installation or deployment, just compile and test. So they can be run often.
- it is easy to add a new test to reproduce a problem once it is identified,
and it augments the regression suite, or to answer a question ("what happen if
this function is not called with a null parameter ...").
There clearly is some overlap between the two, but they are complementary as they both offer advantages.
Now, like any software engineering process, testing has to be taylored according
to the project needs.
With a large legacy codebase, legacy in the sense of not unit tested, I would
recommend to restrict unit tests to new features added to the code as
unit tests can be hard to introduce. In this regard,
I can only second (third ?) the recommendation of the "Working
Effectively with legacy code" book to help bringing unit testing in an existing
codebase.