Verified Code is Correct Code

(Even if it's not right)

What is a unit test?

I will use function as a synonym for a unit of work.

Given that, a unit test is code that calls a function, passes in a set of dependencies (parameters) and makes an assertion about what the return value should be.

There is not an assumption of a 1:1 relationship between a function and its tests.  Many functions will require multiple tests to verify different parameter values.

When should I write unit tests?

For the purposes of proving correctness, it makes no difference when the tests are written.  However, you will become a better programmer if you force yourself to consider how a function should behave before writing it.  You will write shorter functions.  You will control your dependencies better.  You will think of error conditions much earlier in the process.

What should I test?

Test your logical branches and boundary conditions.

Don't test frameworks or third party dependencies.

Mocks and Stubs and Spies, oh my!

Usually ( > 90%) of the time, you can achieve what you need from your dependencies with spies.

If you need actual logic inside your testing dependency, you need a mock

When using any mock, stub, spy etc, your test will only be as correct as your dependency allows.

Gotchas

new Date(), DateTime.Now, etc

Global, mutable state

Mocks that are too smart for their own good.

Implicit dependencies

Forgetting edge cases: "What happens if this parameter is null?"

Correct Code

By Michael Atkins