If you are just getting started with unit testing you might
run into some common pitfalls and get a sour taste in your mouth. Again, this
is not meant to be an entire course on testing. There are already entire books
on that. This is specifically regarding writing unit tests for controller
classes. We write so heavily on testing controller classes because test-driving
the controllers ensures they have a good and proper design. It is nearly
impossible to test-drive code that ends up with a bad design. Code with bad
design tends not to be testable at all, so it is a very objective gauge. A good
controller unit test will run very fast. We are talking 2000 unit tests all
running within ten seconds. You might wonder how that is possible. It is possible
because .Net code runs very fast, and if you are running unit tests, you are
only waiting on the processor and RAM. Unit tests run code only within the
AppDomain, so we do not have to deal with crossing AppDomain or Process
boundaries. You can quickly sabotage this fast test performance if you break a
fundamental run of unit testing, and that is allowing out-of-process calls.
Out-of-process calls are orders of magnitude slower than in-process calls, and
your test performance will suffer. Ensure that you are faking out all
controller dependencies, and your test will continue to run very fast.
You also want your unit tests to be self-sufficient and
isolated. You might see repeated code and think you need to refactor your unit
tests. Resist this temptation and only create test helpers for the
cross-cutting concerns. The DRY principle (Don’t Repeat Yourself) does not
apply to test code as much as it does to production code. Rather, keeping test
cases isolated and self-contained reduces the change burden when the production
code needs to change. It is also more readable if you can scan a unit test and
see the context all in one method.
The tests should also be repeatable. That means no shared
global variables for test result state, and no shared state between tests in
general. Keep a unit test isolated in every way, and it will be repeatable,
order-independent and stable.