Unit Testing 101

This article is part of the serie: clean-code

Posted Jan 29, 2024
2 min reading time

If you don’t know the rules, you’ll end up doing things the hard, costly way. The next step in our journey to quality code is Unit Testing 101 — the other thing that is either not taught or taught using overly simple examples.

When it comes to testing, I’ve found that most examples of TDD are on ideal and simple scenarios, understandable even to a kindergarten student. However, in reality, confusion arises.

Options are endless, but not every approach results in meaningful tests. Some tests may become brittle, requiring a lot of extra work with each change, etc.

For testing, we need mocks, stubs, etc., and believe it or not, there are great rules for when and how to apply them.

Legacy code = code that has no unit test coverage

In the previous chapter, we focused on DDD and introduced a couple of key factors that make testing easier:

  • Encapsulation
  • Separating object behavior and state from persistence
  • Layered architecture and other great patterns

All are key factors in creating tests.

Now, it’s time to delve into the principles I’ve mentioned, and for that, your go-to source is Vladimir Khorikov - Unit Testing - Principles, Practices, and Patterns.


  • The characteristics of a robust unit test
  • Proven techniques for effective test writing
  • Strategic choices for deciding what to test
  • The value and insights derived from each test
  • Best practices for testing dependencies
  • …and more

But dear CEOs, Founders, when it comes to tests, here’s my perspective: remember Goodhart’s Law: ‘When a measure becomes a target, it ceases to be a good measure.’ The key factor is indeed knowing what to test and understanding the security the tests provide!

So fellow Developers, if you encounter a “100% test coverage” requirement - RUN!

Stay tuned - Summaries from the book are coming soon!

Also explore practical testing wisdom with a video from Derek Comartin, a favorite author of mine. Watch as he navigates usual but tricky scenarios without relying on mocks in Testing WITHOUT Mocks or Interfaces! - YouTube


  • testing time (the DateTime.Now issue)
    • 01:15 using interfaces - see also .NET8 ITime and TimeProvider
    • 04:53 using delegates (functions)
    • 07:08 passing in data
  • 08:54 testing API calls (HttpClient)

📌 Make sure you and your team subscribe (follow me) on  LinkedIn so you don’t miss out on the latest insights!

Further Reading
Simple API - Integration Problems and Patterns

Even the simplest distributed system – yes, even integrating against a single API – can pose significant challenges (more than 80% of solutions that SMEs have). Mind-blowing, right!?

Microservices RED Flags - Designing Microservices the Right Way

Remember, business goals are rarely about having a top-notch system!

Finally, we have arrived at the point where we can discuss the pinnacle of modern software architecture: microservices.

6 Little Lines of Fail - Everything is Distributed

In today's tech-driven world, even the simplest-looking code can wreak havoc if not handled by seasoned experts. This's why technical experts are not just "nice to have" for companies, but a crucial …