Unit testing is all about testing your code in isolation from its dependencies. Why is it important to isolate your code from its dependencies? There may be several reasons:
- A dependency introduces a requirement to set up and configure the environment in which the test executes. A prime example of this scenario is the use of ADO.NET to communicate with a relational database. If your unit communicates with a database, you can only test that unit by setting up and configuring the database. This may require you to install database software on your the machine executing the test. Most Visual Studio developers probably already have some version of SQL Server installed, but not everyone would like to have to install that other database product.
- A dependency may still be in development (or even not yet created at all), so will contain all sorts of missing features and bugs.
- A dependency may not be readily available. Examples of this may be expensive third-party libraries, where you can only install the library on a few workstations.
- A dependency introduces non-determinism into the unit. This could be a random number generator or the current date and time. Most of the standard sources for non-determinism (Random, RandomNumberGenerator, DateTime) are defined in mscorlib, so you can’t avoid having a dependency to the assembly in which they are defined, but you should treat those classes with care in any case (more on this on a later date).
On the other hand, many other dependencies are perfectly safe in unit testing context. Do you need to isolate your code from System.Xml or System.Design? That wouldn’t really make sense. These dependencies are very stable – they are part of the BCL and will not change unless you run your application on a different framework version, and even then, the framework versions are backwards compatible.
Stable dependencies may extend to third-party libraries. If you use a third-party library which you have determined to be robust and readily available, there may not be any reason to isolate your code from it.
The types of dependencies listed above, however, introduce a certain amount of instability to your unit. To distinguish them from stable dependencies, I suggest the term volatile dependencies. These are the types of dependencies from which you need to isolate your unit when writing unit tests.