I find two common, basic reasons:
- In manager’s opinion unit testing is “expensive”, because maintaining unit tests requires effort (doubles the effort needed to modify the code itself) and quality of unit tests is hard to verify (so manager won’t rely on them…).
- Unit testing is a pain, because every test needs “context preparation” (database, configuration, external services) which is annoying to set up (and takes a lot of time).
Point 1 is quite simple to overthrow - maintenance effort reduces with increasing developers’ experience and this effort can’t be considered as a waste, because it helps you decrease the chance of introducing errors in modified code. What is more - I’d risk making a statement that if adjusting the tests in your solution takes a lot of time, it’s a proof of solution’s poor design. And you can validate (at least partially) unit test quality with code coverage tools.
Point 2 seems to be a bigger problem, at least in theory. Context may be a problem indeed, but unit test doesn’t bear its name for no reason - it has to test “the unit” and this unit needs to get “isolated”, so you test your particular, separated case / scenario path, disregarding the rest of functional domain. How can we isolate “the unit”? By mocking.
And now we’re reaching my point - I’d like to present you a short review of mocking tool for .NET named Typemock Isolator (http://www.typemock.com/
What does it mean - “to mock”?
In shortest possible words - “to mock” means to fake behavior of part of the solution which is not being tested currently. What’s the gain? Imagine that you’re going to test functional business logic in your application, but the part of code you’re going to test relies on external service that takes a lot of time to execute. Your goal is not to test the external service, because it has already passed acceptation tests - you can assume it’s working properly and now you just want to test business logic that uses external service call outcomes. If your unit tests call external service, they will take ages to execute each time - that’s a burden it would be nice to avoid.
Or, imagine that you can call external service in limited time-frame (it’s accessible only between 1pm and 2pm). Or it’s published as pay-per-use (external service vendor). Or its responses are somehow dependent on physical date on external server (answers will be different depending on when service was called). In all those cases (and many, many more) you’d like to mock such a service.
So, external services are great for being mocked. Anything else? Yes, for example: databases. Tests may be executed in random order and they may leave quite a mess in the database. Cleaning this mess and re-creating proper test conditions may require some time. Even if it means just few seconds for each test, number of your tests will hopefully keep increasing and so will their execution time. Tests are meant to be useful and half an hour long test ritual before every commit is more like a burden than any help.
Te Be Continued …