<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://erwin.vandervalk.pro/feed.xml" rel="self" type="application/atom+xml" /><link href="https://erwin.vandervalk.pro/" rel="alternate" type="text/html" /><updated>2022-04-22T11:01:32+00:00</updated><id>https://erwin.vandervalk.pro/feed.xml</id><title type="html">Erwin’s Blog</title><subtitle>Blogging on life, the universe and everything (but mainly tech)</subtitle><entry><title type="html">A startup journey</title><link href="https://erwin.vandervalk.pro/new-startup/" rel="alternate" type="text/html" title="A startup journey" /><published>2022-04-20T08:47:57+00:00</published><updated>2022-04-20T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/new-startup</id><content type="html" xml:base="https://erwin.vandervalk.pro/new-startup/">&lt;h1 id=&quot;joining-a-new-startup-smart-cloud&quot;&gt;Joining a new startup Smart Cloud&lt;/h1&gt;

&lt;p&gt;Last week, I agreed to join a new startup Smart Cloud (working title). What the startup is about and what we’re going to build I will hopefully be able to talk more about in the future.&lt;/p&gt;

&lt;p&gt;But for now, I thought it would be interesting to document our journey through technology from the absolute beginning to (hopefully) a thriving billion dollar success (or an abysmal failure and deep shame but more likely, something in the middle).&lt;/p&gt;

&lt;p&gt;So, in the near future, I hope to be able to write about:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Which principles do we follow?&lt;/li&gt;
  &lt;li&gt;What technologies do we pick and why?&lt;/li&gt;
  &lt;li&gt;Which practices do we use and why?&lt;/li&gt;
  &lt;li&gt;What type of architecture do we aim for and how does it evolve?&lt;/li&gt;
  &lt;li&gt;What do we value (both technically and culturally)?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And as the system evolves:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;What works and what doesn’t?&lt;/li&gt;
  &lt;li&gt;What did we change?&lt;/li&gt;
  &lt;li&gt;What can’t we change anymore but wish we could?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Anyway, I’m super excited to get started on this journey.&lt;/p&gt;</content><author><name></name></author><category term="Startup" /><summary type="html">Joining a new startup Smart Cloud</summary></entry><entry><title type="html">Testing without mocks - databases</title><link href="https://erwin.vandervalk.pro/testing-without-mocks-databases/" rel="alternate" type="text/html" title="Testing without mocks - databases" /><published>2021-12-31T08:47:57+00:00</published><updated>2021-12-31T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/testing-without-mocks-databases</id><content type="html" xml:base="https://erwin.vandervalk.pro/testing-without-mocks-databases/">&lt;p&gt;Databases are at the heart of most LOB applications, and so they should also be at the heart your unit testing
strategies. In this post, i’ll go into some of the mechanics of how to test without mocks. But because I’m finding that
this is a huge topic, this post only focusses on persistence (databases).&lt;/p&gt;

&lt;p&gt;This post combines information from previous post, including &lt;a href=&quot;../stop-mocking&quot;&gt;why&lt;/a&gt; you should 
stop using mocking libraries, some &lt;a href=&quot;../testing-tricks&quot;&gt;tips and tricks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’ll try to provide some coding examples to these topics later.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TLDR;&lt;/h2&gt;

&lt;p&gt;When writing unit tests for LOB applications, I want to include the database as much as possible. It’s 
a vital aspect of the system, so I won’t ignore this aspect. Where possible and practical, I’ll try to write tests
that include a real database. If this is not effective / efficient / possible, i’ll try to see if I can
use or write an in-memory test double. Only if that’s not possible will I revert to writing
(hand crafted) mocks. This approach gives me the most confidence that my system is actually working correctly.&lt;/p&gt;

&lt;h1 id=&quot;the-elephant-in-the-room-persistence&quot;&gt;The elephant in the room: Persistence&lt;/h1&gt;

&lt;p&gt;Let’s first talk about the elephant in the room when it comes to writing tests without mocks, 
which is the database (or better said, data persistence).&lt;/p&gt;

&lt;p&gt;When discussing mocking, most people agree that that truly external dependencies (such as 
external services) should be mocked. But when it comes to data persistence, it’s not so clear.&lt;/p&gt;

&lt;p&gt;Some people consider the database to be one of those external systems, so they’ll mock it out completely. 
Other people say that they design their software persistence ignorant and so they don’t have to mock out 
the database.&lt;/p&gt;

&lt;p&gt;I would argue that testing your data persistence is actually really important. In line of business applications, 
data persistence is one of the most important concerns. It’s the place where most performance problems
 stem from and the root of a lot of complexity.&lt;/p&gt;

&lt;p&gt;But there is &lt;strong&gt;no silver bullet (tm)&lt;/strong&gt; when it comes to handling persistence. The right approach balances
out the requirements of the application that’s being tested with the technologies used.&lt;/p&gt;

&lt;p&gt;Keep in mind, there is a huge variety in persistence technologies:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Relational databases (in all their various incarnations, such as MsSql, MySql, Postgress, Oracle, etc..)&lt;/li&gt;
  &lt;li&gt;Event Stores (EventStore, Sql Stream Store, marten, etc.)&lt;/li&gt;
  &lt;li&gt;Key Value Stores / document databases (MongoDB, AWS Dynamodb, Azure CosmosDB, RavenDB, etc..)&lt;/li&gt;
  &lt;li&gt;Object stores (Azure Blob storage, S3, etc..)&lt;/li&gt;
  &lt;li&gt;Indexers (elastic search, Azure Cognitive search, etc..)&lt;/li&gt;
  &lt;li&gt;Message brokers, Queues, service busses, etc..  (yes, they actually do store data)&lt;/li&gt;
  &lt;li&gt;many others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These technologies have vastly different api signatures, characteristics and capabilities. But where 
in the past, most applications just used one type of database (Relational), it’s become mainstream now
to use a mix of these technologies.&lt;/p&gt;

&lt;p&gt;So, if you’re building a LOB application, you’re likely going to have to tackle several of these api’s.&lt;/p&gt;

&lt;h1 id=&quot;heuristics-on-choosing-an-approach&quot;&gt;Heuristics on choosing an approach&lt;/h1&gt;

&lt;p&gt;There is no one size fits all approach on how to handle these persistence technologies in 
your unit tests. They are simply too diverse to make generalized statements about. So what I rely on
is a set of heuristics, that try to combine the unique requirements of the system with basic guiding 
principles.&lt;/p&gt;

&lt;p&gt;First of all, what I want to get out of my tests is (From my post on &lt;a href=&quot;../well-written-tests&quot;&gt;well written tests&lt;/a&gt;):&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;They are easy to write and maintain.&lt;/li&gt;
  &lt;li&gt;They run fast enough (and ideally in parallel).&lt;/li&gt;
  &lt;li&gt;They provide actual value (they help you write code and catch issues).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This provides an interesting challenge. Usually there are these solutions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimize for test value: Real db&lt;/strong&gt; You get the most value (3) when you run your tests against a &lt;strong&gt;real&lt;/strong&gt; database 
(more on that below). However, this &lt;em&gt;can&lt;/em&gt; come at the expense of how easy they are 
to write (1) and how fast they run (2). There are techniques you can use to improve (1) and (3) though, which i’ll describe
below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimize for test execution speed: Fake db&lt;/strong&gt;. You can fake your database, which optimizes for speedy execution of tests, because 
there is no real logic. However, you then decrease the value (3) because you don’t know if the mock behaves exactly
as the real thing and it is extra code to write / maintain (2). Yes, a mocking library can help, but I get more 
mileage by hand crafting my mocks IF the api surface is not too big. More on that below.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Optimize for developer efficiency&lt;/strong&gt;. Most databases have a way to provide an in-memory implementation. For example,
for relational databases you can use &lt;a href=&quot;https://www.sqlite.org/index.html&quot;&gt;SQLite&lt;/a&gt;, or an in-memory eventstore (SQL 
Steam Store). These usually are fast (2) and easy to use (1) but are an imperfect implementation so they may have 
differences in how they respond in certain situations. Therefor, they usually give you less confidence in the overall
solution and therefor less value (3).&lt;/p&gt;

&lt;h2 id=&quot;picking-an-approach&quot;&gt;Picking an approach&lt;/h2&gt;
&lt;p&gt;So, given these heuristics, how do you choose an approach?&lt;/p&gt;

&lt;p&gt;First of all: &lt;strong&gt;You don’t have to limit yourself to a single choice.&lt;/strong&gt;. People so often look for the single and only
best way to handle an approach. But if you find that you have a situation that a simpler approach works great for 
80% of your tests but 20 % really requires a specialized and more complex approach, by all means, use both approaches.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;You have a straight forward application, not much business logic, relatively simple queries, etc..
But there are a couple of rather complex  and very important queries. Use a simple approach like an in-memory implementation
for the simple approach but use a real database for the complex queries.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another example when you use CQRS:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;You are applying CQRS in (parts) of your application. This means you have different access patterns 
for your write model vs your read model. The write model typically involves reading / writing single items by ID
whereas the read model involves complex queries. Use an in-memory approach for the write side, and a real
db for the read model.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ok, another example &lt;em&gt;(because most people don’t think of their software as simple / straight forward)&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;You have a complex application. Lots of business rules, complex queries, etc. 
But you also have to manage some reference data. This can be covered using simple crud. 
Use a real database for the complex scenarios, and a simple (in-memory) approach for the crud screens.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Last example, I promise:&lt;/p&gt;
&lt;blockquote&gt;
  &lt;p&gt;You write your business logic tests using an in-memory database, because this allows you to focus
on the business logic you’ve just added. However, you also have tests that cover complete business scenarios
at api level. These tests have a bigger scope and there it makes sense to use a real database.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, ask yourself the following questions:&lt;/p&gt;

&lt;h2 id=&quot;1-how-much-are-you-tied-to-the-actual-logic-of-the-store&quot;&gt;1. How much are you tied to the actual logic of the store?&lt;/h2&gt;
&lt;blockquote&gt;
  &lt;p&gt;This is one of the most important questions when deciding what to do with the database.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more you rely on the specific implementation of the database (for example for performance reasons),
the less mileage you’ll get from using a fake version.&lt;/p&gt;

&lt;p&gt;For example, if you use a relational database and heavily rely on joins, complex queries, materialized views, 
specific indexing patterns, or other fancy things, then you might not get much benefit from an in-memory 
implementation, because it doesn’t give you the fidelity that you’re looking for. Another example would be 
specific partitioning requirements in dynamodb or kafka for scalability reasons.&lt;/p&gt;

&lt;p&gt;However, if you’re simply persisting objects, returning them and have only basic querying over them, or you 
are just testing straight forward business logic then an in-memory implementation is usually good enough. 
Usually, happy paths work really well with a in-memory double, but exceptions and platform specific 
optimizations do not.&lt;/p&gt;

&lt;h2 id=&quot;2-is-there-a-good-in-memory-implementation&quot;&gt;2. Is there a good in-memory implementation?&lt;/h2&gt;

&lt;p&gt;Most often, a good in-memory implementation is worth it’s weight in gold. Oh wait, software doesn’t weigh much, but you 
get the gist. What I mean is, a good in-memory implementation can cover most common scenarios and that might make this 
a very effective option. Now, if you depend heavily on the implementation specifics of your database, for example 
for performance reasons, then you’re probably better off NOT using a real database.&lt;/p&gt;

&lt;p&gt;If there is not a good in-memory implementation, perhaps you can write one. But if that’s effective depends on the size of the api surface
and of course, how much you really need from your implementation.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I’ve had really good results testing my own business logic with in-memory event stores, in-memory sql databases (sql lite). Sometimes, 
you have edge cases. For example in relational databases, each database subtle differences in sql dialect, and it’s own way of handling
indexes, triggers, constraints etc. These can trip you up if it’s the only thing you rely on.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Another example is when using an in-memory event store. Regular business logic tests work great, but when it comes
to testing your logic for when network connection failures occur, it can be better to work with a real database. Docker 
works really well, but more on that later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;3-how-big--complex-is-the-api-surface&quot;&gt;3. How big / complex is the api surface?&lt;/h2&gt;

&lt;p&gt;The size and complexity api surface of your persistence can also determine your strategy. A key value store, event 
store or document database typically has a very narrow api surface. This means it’s relatively easy to create test 
doubles or even complete in-memory implementations for these relatively simple.&lt;/p&gt;

&lt;p&gt;The thing that’s usually difficult to implement is the querying api. If you have something that uses linq expressions
or fairly straightforward filter parameters, then it may be possible to stick with in-memory test doubles. However, you
don’t want to go overboard and have to implement a complete querying language, just to run your unit tests.&lt;/p&gt;

&lt;p&gt;On the other end of the spectrum are relational databases. Due to their nature of having (often complex) relations between
tables, and having very rich querying options over them, typically makes it very difficult to write your own mocks against.&lt;/p&gt;

&lt;h1 id=&quot;tips-for-testing-with-in-memory-implementations&quot;&gt;Tips for Testing with in-memory implementations&lt;/h1&gt;

&lt;p&gt;An in-memory test double is usually great and my preferred option when writing business logic tests.&lt;/p&gt;

&lt;p&gt;Ideally, you have one provided to you, but if not, often they are not too difficult to write (assuming your api surface 
is not to big / complex).&lt;/p&gt;

&lt;h2 id=&quot;take-control-of-eventual-consistency&quot;&gt;Take control of eventual consistency&lt;/h2&gt;

&lt;p&gt;Eventual consistency is often used to improve the throughput of your system. This is often (but not required for)
CQRS or event sourced applications. How to handle this gracefully probably warrants an entire blog post, but for now,
a short discussion of this topic:&lt;/p&gt;

&lt;p&gt;One of the difficult things I’ve found in unit testing is handling eventual consistency. Typically, you take an action,
then you verify if the side effects have occurred. Polling or retries are often used to handle this.&lt;/p&gt;

&lt;p&gt;But with eventual consistency, how do you distinguish if the action hasn’t happened yet from a failure 
where the action is never going to happen? With everything being in-memory, a successful test will often run really
fast, but a failure can take a while, because you have to retry enough and wait long enough to be sure the test fails 
for the right reasons.&lt;/p&gt;

&lt;p&gt;One of the things I’ve used very successfully is to remove or completely control the eventual consistency from my 
in-memory implementations.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;When the action happens, synchronously process all side effects.&lt;/li&gt;
  &lt;li&gt;Make the side effects observable. Create a Task that completes when the side effects have happened. This way,
you can listen for the effects to have happened and make things much more deterministic.&lt;/li&gt;
  &lt;li&gt;Control when to run the eventual consistent actions. For example, introduce a ‘ProcessAllMessages()’ method 
that will then execute your logic.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;testing-your-in-memory-implementation&quot;&gt;Testing your in-memory implementation&lt;/h2&gt;
&lt;p&gt;If you have an in-memory implementation, you must have some level of confidence that it actually works.&lt;/p&gt;

&lt;p&gt;One method I’ve used in the past is to create a body of tests that cover both a real and in-memory 
implementation. This makes sure that your in-memory version responds (within reason) the same as 
the real thing. It’s also a good place to add additional tests once you find a discrepancy.&lt;/p&gt;

&lt;p&gt;To do this, create a base class where you place your tests. Then create two derived classes, that will set up the
real or in-memory instance. This way, the same tests run against two databases.&lt;/p&gt;

&lt;h1 id=&quot;tips-for-testing-with-hand-crafted-test-doubles&quot;&gt;Tips for testing with hand-crafted test doubles&lt;/h1&gt;

&lt;p&gt;A hand crafted test double is handy when:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;no good in-memory implementation is available&lt;/li&gt;
  &lt;li&gt;The api surface is reasonably narrow, but creating a real in-memory implementation would be too complex.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Tips:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Make your test doubles easily observable.&lt;/li&gt;
  &lt;li&gt;Hide eventual consistency.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1 id=&quot;tips-for-testing-with-real-db-implementations&quot;&gt;Tips for Testing with real db implementations&lt;/h1&gt;

&lt;p&gt;Testing with a real database implementation gives you a lot of confidence that
your code actually does what it needs to do.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;It’s still not going to be 100% the same. For example, in production, you’ll likely use
a sql server cluster, not a sql localdb instance. Or, you are using dynamodb, but locally 
you have only a few partitions, so sharding is not so much of an issue.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2 id=&quot;dockerize-your-setup&quot;&gt;Dockerize your setup&lt;/h2&gt;

&lt;p&gt;If possible, try to use docker to spin up your local databases. This means setting up your
environment is much easier (for other developers) and it (likely) makes your tests also 
portable to run on your build server without requiring software to be pre-installed.&lt;/p&gt;

&lt;h2 id=&quot;provide-a-proper-level-of-isolation&quot;&gt;Provide a proper level of isolation&lt;/h2&gt;

&lt;p&gt;A database is almost by definition a shared resource. Multiple instances of your application
and multiple threads within your application all compete with each other to access the same 
database.&lt;/p&gt;

&lt;p&gt;In unit tests, sharing state between tests is a source of really hard to find bugs. When you run
a test in isolation, it works fine, but when running all of them (or even worse, only on the
build server) then they start failing.&lt;/p&gt;

&lt;p&gt;Also, when you run your tests in parallel, you don’t want your tests to interfere with each other
either.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Try if possible to avoid sharing your database amongst your tests.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So how do you do this?&lt;/p&gt;

&lt;h3 id=&quot;option-1-use-a-database-per-test&quot;&gt;Option 1: Use a database per test.&lt;/h3&gt;

&lt;p&gt;This is an option if your database is not too big. With a small schema, it doesn’t take much time to create
/ drop your database.&lt;/p&gt;

&lt;p&gt;I once used this technique, but after a while it became a bit too slow. Also, it required me to seed the database
every time with the same data. So, to avoid this, I created a small tool that created a database once, seeded
it with data, then created a backup of the database. I then restored the backup for each test. This proved to be
much faster.&lt;/p&gt;

&lt;h3 id=&quot;option-2-use-a-schema--namespace--table-per-test&quot;&gt;Option 2: Use a schema / namespace / table per test.&lt;/h3&gt;

&lt;p&gt;I often use this technique when using dynamodb. If you allow your test to create a random table
name, then each test get’s it’s own table. So, they don’t interfere with each other. I also did this when using elastic. 
Simply create an index per test.&lt;/p&gt;

&lt;p&gt;Some databases make it light weight to create / drop databases or database tenants. Then this
would also work to provide some form of isolation.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Don’t forget to delete your data after your test.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Also.. provide a tool to clean up your data manually, because the cleanup logic doesn’t always run.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;option-3-share-a-database-but-be-careful&quot;&gt;Option 3: Share a database but be careful&lt;/h3&gt;

&lt;p&gt;One system I worked on in the past had a huge database schema. Recreating this database for each test
would have been completely impractical. So, in order to make the tests run at an ok speed, I only created
a new database per test collection.&lt;/p&gt;

&lt;p&gt;Within the test collection, I was sharing the database. This means that I had to be really careful
in how to write the tests. For example, it’s fine to insert some data with a unique key, then read
that data back again. Since the key is unique for your test, you (likely) won’t get collisions.&lt;/p&gt;

&lt;p&gt;Search is a tricky one here. Because, you can find data created by other tests. This means, you’ll
either need to make sure you narrow your search appropriately or that you can handle arbitrary large
result sets (page through all data found until you find what you’re looking for).&lt;/p&gt;

&lt;h3 id=&quot;not-recommended-techniques&quot;&gt;Not recommended techniques&lt;/h3&gt;

&lt;p&gt;I’ve seen various other techniques around this.&lt;/p&gt;

&lt;p&gt;Using a real database instance but never cleaning it up is not something I recommend. It leaves too much 
crap behind, so after a while you have no idea what happened.&lt;/p&gt;

&lt;p&gt;Using locks, then reverting everything once done. I don’t recommend this, because it doesn’t represent
the way the transactions would normally complete. Also, you might get a lot of deadlocks in your database.&lt;/p&gt;

&lt;p&gt;Manual cleanup after the tests and having each test run separately is another pattern I don’t really like. 
It’s too easy to forget to add some cleanup code as the system grows and then you get test instability.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In this post, I’ve described various techniques on how you can handle databases when you don’t want to 
use mocking libraries. As usual, it turned out to be a longer post than I had hoped, so I’ll publish this
now and will come up with some code examples later.&lt;/p&gt;</content><author><name></name></author><category term="unit-testing," /><category term="practices" /><summary type="html">Databases are at the heart of most LOB applications, and so they should also be at the heart your unit testing strategies. In this post, i’ll go into some of the mechanics of how to test without mocks. But because I’m finding that this is a huge topic, this post only focusses on persistence (databases).</summary></entry><entry><title type="html">Stop making a Mock</title><link href="https://erwin.vandervalk.pro/stop-mocking/" rel="alternate" type="text/html" title="Stop making a Mock" /><published>2021-12-05T08:47:57+00:00</published><updated>2021-12-05T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/stop-mocking</id><content type="html" xml:base="https://erwin.vandervalk.pro/stop-mocking/">&lt;p&gt;I don’t like mocks anymore. I used them heavily in the past, but now that I’ve moved away from this approach,
my tests have become a lot better. In this post, I hope to convince you to do the same. In a future post, i’ll
describe better ways to test.&lt;/p&gt;

&lt;h2 id=&quot;tldr&quot;&gt;TLDR;&lt;/h2&gt;

&lt;p&gt;Don’t rely on Mocking libraries. Reliance on mocking libraries causes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;increased coupling between classes.&lt;/li&gt;
  &lt;li&gt;reduced readability of your tests.&lt;/li&gt;
  &lt;li&gt;reduced maintainability of your application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t blindly declare interfaces on every class. Introduce abstractions when you need them, not as a reflex.&lt;/p&gt;

&lt;p&gt;Do:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Design your classes and components so that truely external dependencies can be isolated.&lt;/li&gt;
  &lt;li&gt;When needed, write hand crafted test doubles to simulate dependencies like external services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Consider this: Can you refactor your code without having to make changes to your tests? If not, you’re in trouble.&lt;/p&gt;

&lt;p&gt;So, stop making a Mock of things and you’ll be better off.&lt;/p&gt;

&lt;h2 id=&quot;background-i-see-mocks-everywhere&quot;&gt;Background: I see mocks everywhere&lt;/h2&gt;

&lt;p&gt;Part of my job is reviewing code written by other teams. As a (primarily) .Net
developer, that means reading a lot of c# code. It’s clear that many developers
have become familiar with Test Driven Development, which is of course a good
development.  However, I’m finding that the .Net Community uses Mocking a lot,
using libraries like &lt;a href=&quot;https://fakeiteasy.github.io/&quot;&gt;FakeItEasy&lt;/a&gt;,
&lt;a href=&quot;https://github.com/moq/moq&quot;&gt;Moq&lt;/a&gt;, &lt;a href=&quot;https://nsubstitute.github.io/&quot;&gt;NSubstitute&lt;/a&gt;
or one of the many other frameworks.&lt;/p&gt;

&lt;p&gt;What I typically see is:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The Single Responsibility principle is followed religiously, so there are a lot of smaller
classes.&lt;/li&gt;
  &lt;li&gt;Most classes have interfaces (dto’s the obvious exception), but there’s only a
single implementation in the codebase.&lt;/li&gt;
  &lt;li&gt;Each is wrapped in it’s own unit test.&lt;/li&gt;
  &lt;li&gt;Each dependency is mocked out in the unit tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/img/stop-mocking-I-see-mocks.png&quot; alt=&quot;see mocking&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These developers clearly think they are getting a lot of benefits from writing 
tests so they use their good intentions to spend a lot of energy to write tests 
that don’t nearly provide them as much benefits as they would have hoped.&lt;/p&gt;

&lt;h3 id=&quot;this-is-the-way&quot;&gt;This is the way&lt;/h3&gt;
&lt;p&gt;When I challenge this mocking approach, I get a lot of push-back: &lt;em&gt;“A unit has to be
a class”&lt;/em&gt;. &lt;em&gt;“If you don’t isolate the class, you’re testing things twice”&lt;/em&gt;. &lt;em&gt;“This is the 
only way(tm)”&lt;/em&gt;. &lt;em&gt;“You must isolate a class, otherwise you’re doing integration testing”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/img/stop-mocking-this-is-the-way.png&quot; alt=&quot;the way&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The thing is, it wasn’t always like this. This post from &lt;a href=&quot;https://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;Martin Fowler&lt;/a&gt; 
describes that classical TDD didn’t used to rely on mocking.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The classical TDD style is to use real objects if possible and a double if it’s
awkward to use the real thing. So a classical TDDer would use a real warehouse
and a double for the mail service. The kind of double doesn’t really matter
that much.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;A mockist TDD practitioner, however, will always use a mock for any object with
interesting behavior. In this case for both the warehouse and the mail service&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Somewhere down the line, the practice of testing &lt;em&gt;units&lt;/em&gt; in isolation, was
translated to testing &lt;em&gt;classes&lt;/em&gt; in isolation and mocking the rest, facilitated
by mocking frameworks. I’ll do my best to describe the problems I’m seeing with
this ‘mockist’ approach to testing and show alternatives to them.&lt;/p&gt;

&lt;h1 id=&quot;the-problems-with-mocking-libraries&quot;&gt;The problems with mocking libraries&lt;/h1&gt;

&lt;p&gt;My biggest problems with the usage of mocking libraries are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;You’re increasing coupling, which limits your ability to refactor.&lt;/li&gt;
  &lt;li&gt;You’re testing the internals of your class, limiting your possibilities to refactor.&lt;/li&gt;
  &lt;li&gt;A mock has to simulate the behavior of your class, so you have to implement some logic twice.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’ll go into these points more below.&lt;/p&gt;

&lt;h2 id=&quot;decreased-maintainability-due-to-increased-coupling&quot;&gt;Decreased maintainability due to Increased coupling&lt;/h2&gt;

&lt;p&gt;Using mocking libraries dramatically increases the number of dependencies a class has. Consider the following diagram.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/img/stop-mocking-class.png&quot; alt=&quot;class-diagram-without-mocks&quot; /&gt;.&lt;/p&gt;

&lt;p&gt;It’s a fairly straightforward set of classes. Class &lt;strong&gt;A&lt;/strong&gt; depends on Class &lt;strong&gt;B&lt;/strong&gt;
and &lt;strong&gt;C&lt;/strong&gt;, which in their turn depend on Class &lt;strong&gt;DB&lt;/strong&gt; and class &lt;strong&gt;DTO&lt;/strong&gt;.
Intentionally, there is no functional description to these classes, but you
could think of class A being a controller, Class B and C providing some form of
business logic and Class &lt;strong&gt;DB&lt;/strong&gt; providing Database Access and Class &lt;strong&gt;DTO&lt;/strong&gt;
being a data transfer object.&lt;/p&gt;

&lt;p&gt;The number of dependencies is fairly low. This makes refactoring a lot easier.
Consider:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;A change to class &lt;strong&gt;DB&lt;/strong&gt;. It will likely impact class &lt;strong&gt;B&lt;/strong&gt; and &lt;strong&gt;C&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;A refactoring where parts the logic of &lt;strong&gt;B&lt;/strong&gt; and &lt;strong&gt;C&lt;/strong&gt; can be re-used and
will be factored in a separate class. This impacts &lt;strong&gt;B&lt;/strong&gt; and &lt;strong&gt;C&lt;/strong&gt; and likely
also &lt;strong&gt;A&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The obvious consequence of this approach is, that, if you change the &lt;em&gt;signature&lt;/em&gt;
of your class, you’ll also have to change all classes that use the signature.&lt;/p&gt;

&lt;p&gt;THe non-obvious consequence of this approach, is that in order to create good
mocks, you’ll also need to know a little bit about the runtime behavior of the
classes being mocked. Not everything can be read from the signature. What data
is being returned? In which order? What kind of validation rules are being
performed by the class calling your method?&lt;/p&gt;

&lt;p&gt;So, if you don’t rely on mocks, you end up with a much decreased maintenance burden.&lt;/p&gt;

&lt;h2 id=&quot;refuctoring-having-to-change-your-tests-when-you-refactor-your-solution&quot;&gt;Refuctoring (having to change your tests when you refactor your solution)&lt;/h2&gt;

&lt;p&gt;When relying on mocks, you have to create a good test double for the actual logic. This means
that your test has to actually have to know deeply about the internal logic of your class. Any
change to the internals of your class means a change to your tests. This is known as a ‘refuctor’ 
(a term coined by Greg Young as far as I know).&lt;/p&gt;

&lt;p&gt;Your test is your safety net while doing changes. Making changes to your safety net when you need to
rely on it is not a very good idea.&lt;/p&gt;

&lt;p&gt;So how do we prevent that? Don’t mock your implementation, but &lt;em&gt;where possible&lt;/em&gt; rely on the real implementation (more on that below.)&lt;/p&gt;

&lt;h2 id=&quot;hard-to-understand-test-tests&quot;&gt;Hard to understand test tests.&lt;/h2&gt;

&lt;p&gt;The arrange-act-assert pattern of tests is often used in conjunction with mocking and &lt;a href=&quot;https://en.wikipedia.org/wiki/Single-responsibility_principle&quot;&gt;SRP&lt;/a&gt;. So badly, that I often
see people adding comments to show which bit of the test actually is part of arranging / acting / asserting. Shouldn’t 
that be clear from the actual code, rather than the tests?&lt;/p&gt;

&lt;p&gt;In the arrange step, you set up your mocks. Often, specific tests have specialized setup requirements. So, each mock setup is every so slightly different. But, because you have
to mock out every interaction, it’s not clear if a specific interaction is there ‘just because(tm)’ or if it’s actually significant for your tests.&lt;/p&gt;

&lt;p&gt;Then you have an act phase. This is usually the best part of your tests. The thing that’s really important. But it’s buried in the rest of your test. So you have to put a //act comment above it
just to call out where it is.&lt;/p&gt;

&lt;p&gt;Then there is the assert. Sometimes you see big lists of assertions, but also often a Mock.Verify(). When you first read this test, 
you have NO idea what’s actually being verified. Then you have to look back to see what’s going on, adding to the overall confusion.&lt;/p&gt;

&lt;p&gt;What’s a better approach to this? The Given-When-Then pattern usually makes much more readable tests. 
Given a certain state, when you perform an action, you observe the following results.&lt;/p&gt;

&lt;p&gt;This focusses much more on the functionality (What the system is supposed to do), rather than on the implementation details (How the system is actually performing it).&lt;/p&gt;

&lt;p&gt;To compare and contrast, I’ve created two solutions in the same repo:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/Erwinvandervalk/Examples.Testing.Corona&quot;&gt;https://github.com/Erwinvandervalk/Examples.Testing.Corona&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One application is written using mocking, the other is not.&lt;/p&gt;

&lt;p&gt;Compare the following test that uses mocking with the one below without:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;                &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;When_saving_new_appointment_then_save_is_invoked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Arrange&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repository&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ICoronaTestRepository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateTimeProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IDateTimeProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;();&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DateTimeOffset&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TimeSpan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;FromHours&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CallTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dateTimeProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetNow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Returns&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sut&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ScheduleTestAppointmentCommandHandler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                &lt;span class=&quot;n&quot;&gt;dateTimeProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scheduleTestAppointmentCommand&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ScheduleTestAppointmentCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;testlocation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;ScheduledOn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;TestSubjectIdentificatieNummer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;number&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;TestSubjectName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Act&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sut&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Handle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scheduleTestAppointmentCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CancellationToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Assert&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CallTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;repository&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;SaveAsync&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;A&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CoronaTestEntity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;That&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Matches&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestSubjectName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; 
                            &lt;span class=&quot;n&quot;&gt;scheduleTestAppointmentCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestSubjectName&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestSubjectIdentificatieNummer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; 
                            &lt;span class=&quot;n&quot;&gt;scheduleTestAppointmentCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestSubjectIdentificatieNummer&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scheduleTestAppointmentCommand&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ScheduledOn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
                        &lt;span class=&quot;p&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CreatedOn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;now&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CancellationToken&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MustHaveHappened&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In this test, I have to set up several mocks, then verify that the right call to save the data actually happened. 
But reading this, I have questions:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;What does datetime actually have to do with the test? Is the current time important? It may be, it may not be.&lt;/li&gt;
  &lt;li&gt;What is this ‘CoronaTestEntity’? Why is it important here?&lt;/li&gt;
  &lt;li&gt;Have I verified every property on the corona test entity? Is it ok now?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The actual logic (calling the command) is hidden between the setup and assertion.&lt;/p&gt;

&lt;p&gt;And, if you have to make changes (for example, change the repository signature), you have to get ready for a LOT of changes. 
Yes, you could probably write this better, but this example closely follows what I see in the wild.&lt;/p&gt;

&lt;p&gt;Contrast that with the following:&lt;/p&gt;
&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Can_schedule_appointment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ScheduleTestRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; 
            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;expectedResponse&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetScheduledTestResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CoronaTestClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ScheduleTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;expectedStatusCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HttpStatusCode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;OK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CoronaTestClient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetTest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

            &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ShouldBeEquivalentTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;expectedResponse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This test works at the api boundary (though it would have worked equally well at the command / query layer). The
test only cares about the things the end user cares about. When you do &lt;strong&gt;X&lt;/strong&gt;, you can observe &lt;strong&gt;Y&lt;/strong&gt;. Anything else 
is not important for this test.&lt;/p&gt;

&lt;p&gt;No, this is not an integration test, because I’m testing a single boundary here. Any external dependencies (such&lt;br /&gt;
the e-mail sending in this example). And as for databases? If the test doesn’t slow you down too much, I would
encourage you to include them in your tests. Otherwise, create a stub at the absolute lowest level.&lt;/p&gt;

&lt;h2 id=&quot;single-responsibility-principle-causes-harm-here&quot;&gt;Single Responsibility Principle causes harm here&lt;/h2&gt;

&lt;p&gt;Bob Martin coined the SOLID Principles, with the Single Responsibility Principle being the one people
remember the best.&lt;/p&gt;

&lt;p&gt;This principle leads you to create small classes, each with their own little responsibility. This means we’re breaking
up the functional problem we’re trying to solve and splitting it into smaller classes. While there is something
to be said for this &lt;em&gt;(but please people, within reason, don’t push it to the extreme)&lt;/em&gt;, it has some serious 
drawbacks when you combine it with writing tests PER Class:&lt;/p&gt;

&lt;p&gt;Your business logic is spread across multiple classes, so the tests that verify them are also scattered.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Input validation (IE: is a field of the right type?) is usually done where you map the request to your model. For example in the controllers.&lt;/li&gt;
  &lt;li&gt;Business rule validation is often done in a domain layer&lt;/li&gt;
  &lt;li&gt;With the exception of validation rules that are easier / better to do in the database. For example, duplicate constraints can very easily be handled in the database in a transactional fashion. Trying to do this in the business layer means you’re going to have&lt;/li&gt;
  &lt;li&gt;Some validations cannot (or shouldn’t) be done transactionally, but are actually part of an asynchronous business process.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In an ideal world, you can look at the tests to get a good understanding of the functionality and rules of the system. When each test only covers a single class, and each class only covers a small part of the functionality, it becomes really hard to get a good overview of the system.&lt;/p&gt;

&lt;p&gt;I don’t have a big problem with SOLID when applied sanely. However, I’m finding that people really go overboard. Then couple that with going
overboard with using mocks and you really set yourself up for trouble.&lt;/p&gt;

&lt;p&gt;Anyway, I favor &lt;a href=&quot;https://dannorth.net/2021/03/16/cupid-the-back-story/&quot;&gt;CUPID&lt;/a&gt; over SOLID any time.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;In this post, I’ve highlighted the issues I have with the use of mocking. As this post has become too long already
I’ll post this now and try to focus on what you can do to avoid mocking libraries in a future post.&lt;/p&gt;

&lt;p&gt;But hey, don’t take my word for it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.thoughtworks.com/insights/blog/mockists-are-dead-long-live-classicists&quot;&gt;https://www.thoughtworks.com/insights/blog/mockists-are-dead-long-live-classicists&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/bliki/UnitTest.html&quot;&gt;https://martinfowler.com/bliki/UnitTest.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;https://martinfowler.com/articles/mocksArentStubs.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><category term="unit-testing," /><category term="practices" /><summary type="html">I don’t like mocks anymore. I used them heavily in the past, but now that I’ve moved away from this approach, my tests have become a lot better. In this post, I hope to convince you to do the same. In a future post, i’ll describe better ways to test.</summary></entry><entry><title type="html">Characteristics of well written tests</title><link href="https://erwin.vandervalk.pro/well-written-tests/" rel="alternate" type="text/html" title="Characteristics of well written tests" /><published>2021-11-15T08:47:57+00:00</published><updated>2021-11-15T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/well-written-tests</id><content type="html" xml:base="https://erwin.vandervalk.pro/well-written-tests/">&lt;p&gt;We don’t write tests ‘just for fun’, but because we believe that it brings certain important benefits. Without (enough of) these benefits, it’s 
just overhead and useless ceremony. So the question is, what are the characteristics that make unit testing worth while? And what issues should we avoid?&lt;/p&gt;

&lt;p&gt;When speaking to various people and reviewing a LOT of code, i’m finding that many people have different thoughts and idea’s about this. I’m quite passionate about automated testing, so I figured I’d jot down my own thoughts here.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I started writing a completely different blog post.. Then from there, this post started to form.. then it became too big. WAY to big. So I cut it down so I can at least get something out. Hopefully, I’ll be able to post the others soon as well.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this post, i’m talking about automated tests, but they apply equally well to unit tests, integration tests, UI tests, etc..&lt;/p&gt;

&lt;h1 id=&quot;characteristics-of-well-written-tests&quot;&gt;Characteristics of well written tests.&lt;/h1&gt;

&lt;p&gt;A good test helps you by:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Bringing you &lt;strong&gt;increased understanding&lt;/strong&gt;. It helps you to write the code, or when reading the tests to understand what the code does.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Protects&lt;/strong&gt; you from mistakes during writing / changing / refactoring and bring you &lt;strong&gt;confidence&lt;/strong&gt; in the correctness of the code.&lt;/li&gt;
  &lt;li&gt;Being &lt;strong&gt;resilient&lt;/strong&gt; against internal changes. It should not fail if you refactor the insides of your test subjects.&lt;/li&gt;
  &lt;li&gt;Be &lt;strong&gt;easily changed&lt;/strong&gt; when changes to api signatures occur.&lt;/li&gt;
  &lt;li&gt;Making software development &lt;strong&gt;faster&lt;/strong&gt;, not slowing you down.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In my mind, if your tests do not have all of these characteristics, that’s a smell. But if they are missing more than one, they might be causing more
harm than good.&lt;/p&gt;

&lt;p&gt;&lt;br /&gt;
Looking at the inverse of these properties can also be interesting. A test should &lt;strong&gt;not&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Slow me down&lt;/strong&gt; when writing or maintaining code. If there’s too much overhead in writing / maintaining / running the tests, they don’t bring me any value. How you factor your code is important as well as at which level you start your tests.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Confuse me&lt;/strong&gt;: If you can’t understand what a test does, how it does things or why it does things, it’s usually not valuable at all. A big reason for this can be the use of mocking frameworks (more) about that in a follow up post.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;undermine my trust&lt;/strong&gt;. If you can’t trust your tests, they are not very valuable. This can happen when your tests don’t catch mistakes made. Probably the coverage or assertions are not good enough to build trust. Another reason to undermine your trust is if they fail without good reason. The tests are too brittle then and, because I have to go in and modify my tests as well, i’m eroding the value that they bring. Flakey tests are the worst, when the tests occasionally fail, usually due to improper test isolation. &lt;em&gt;Looking at you, static mutable state!&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;how-to-achieve-these-characteristics&quot;&gt;How to achieve these characteristics?&lt;/h2&gt;

&lt;p&gt;Achieving the characteristics above is not as simple. So, how can you achieve these characteristics?
Each test should:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;have a clear &lt;strong&gt;purpose&lt;/strong&gt;. Sometimes this might mean test a single thing (even if the single thing is a complex business scenario). The name of the test is important, but so is the way you write it.&lt;/li&gt;
  &lt;li&gt;actually protect you from &lt;strong&gt;real issues&lt;/strong&gt;. I’ve seen too many tests that don’t actually protect you from anything. I’ll probably write another blog post later about things not worth testing.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Draw attention&lt;/strong&gt; to the things that are important in your test, while hiding the things which are not. Think deep and hard about what you want your test to express. What are the things that are different in this test from the other tests? This ties in again to it’s purpose. Hiding the unimportant ceremony in helpers (such as data builders, fixtures, helper methods, etc) has the benefit of both &lt;strong&gt;focussing attention&lt;/strong&gt; on what IS important but also allowing you to &lt;strong&gt;reuse&lt;/strong&gt; the logic.&lt;/li&gt;
  &lt;li&gt;Avoid &lt;strong&gt;static mutable state&lt;/strong&gt; like the plague. Static mutable state is the thing that makes your test run fine when running them one at a time, but fail when you run them together, or on the build server.&lt;/li&gt;
  &lt;li&gt;Be written at the &lt;strong&gt;appropriate level&lt;/strong&gt; of technical complexity. Business oriented components have different requirements than more technical components.&lt;/li&gt;
  &lt;li&gt;Clearly express the &lt;strong&gt;reason for failures&lt;/strong&gt;. Tests will eventually fail (otherwise, what’s their purpose?). When a test fails, should be quickly clear why they fail, ideally without the need for debugging. I’ve often found printing log messages to the test output window is a very powerful method for this..&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In a future post, I’ll try to write more about how I typically structure my tests and what things to avoid.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;With these characteristics, I’ve often found my tests to be easy to understand (at least to me), easy to maintain. Hopefully, you find it useful.&lt;/p&gt;</content><author><name></name></author><category term="unit-testing," /><category term="practices" /><summary type="html">We don’t write tests ‘just for fun’, but because we believe that it brings certain important benefits. Without (enough of) these benefits, it’s just overhead and useless ceremony. So the question is, what are the characteristics that make unit testing worth while? And what issues should we avoid?</summary></entry><entry><title type="html">Testing tricks</title><link href="https://erwin.vandervalk.pro/testing-tricks/" rel="alternate" type="text/html" title="Testing tricks" /><published>2021-11-15T08:47:57+00:00</published><updated>2021-11-15T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/testing-tricks</id><content type="html" xml:base="https://erwin.vandervalk.pro/testing-tricks/">&lt;p&gt;In my previous &lt;a href=&quot;../well-written-tests&quot;&gt;post&lt;/a&gt;, I expressed some characteristics
of well written tests. In this post, i’d like to show some techniques to help
achieve these characteristics. In a future post, I’ll try to focus more on
techniques and patterns to avoid.&lt;/p&gt;

&lt;h1 id=&quot;an-example-test&quot;&gt;An example test&lt;/h1&gt;

&lt;p&gt;I’m going to use an extremely simplified example to demonstrate some of the
techniques here.&lt;/p&gt;

&lt;p&gt;Here’s the example, including all the classes involved that i’m going to talk
about in the next chapters:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/testing-tricks/party-class-diagram.png&quot; alt=&quot;class-diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In this example, we’re testing a system to create registrations for a party.&lt;/p&gt;

&lt;p&gt;Have a look &lt;a href=&quot;https://github.com/Erwinvandervalk/erwinvandervalk.github.io/tree/main/src/good-tests&quot;&gt;here&lt;/a&gt; for
the code accompanying this post.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The example is a bit contrived but I found it a challenge to come up with something
that is both useful to explain the topic, but small enough not to distract from the 
concepts. So, I’m only including a domain object and a store to save it. No
http api, command handlers, query handlers, etc. Maybe I’ll enrich the example for 
future posts.&lt;/p&gt;
  &lt;h2 id=&quot;fixtures-and-test-helpers&quot;&gt;Fixtures and test helpers&lt;/h2&gt;
&lt;/blockquote&gt;

&lt;p&gt;To test some functionality, there is quite a bit of testing setup
needed. Usually, you have to construct the Subject Under Test, including all of it’s
dependencies. Then you have to create some data to use for testing. And then you
have to assert the outcome. So many times do I see the subject under test being
created in the test itself, including some or many of it’s dependencies (or, if
you use mocks, set up the mocks in each test).&lt;/p&gt;

&lt;p&gt;Duplicating the construction of your classes in each test case makes maintaining
your tests much harder. When you need to change the dependencies of your test,
all of a sudden you have to modify dozens of tests. Not fun at all!&lt;/p&gt;

&lt;p&gt;I very much try to hide things that are not relevant for my tests in helper
methods (if I can only re-use them in a single test) or in a separate fixture
class. I find that this has several big benefits for me:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;It draws attention in my test only to the important bits.&lt;/li&gt;
  &lt;li&gt;I build up a library of re-usable functionality, so future tests are much
easier to write.&lt;/li&gt;
  &lt;li&gt;It reduces the amount of maintenance I have to perform.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s an example of the fixture:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PartyFixture&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestLoggerProvider&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LogProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyFixture&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ITestOutputHelper&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;LogProvider&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestLoggerProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InMemoryDocumentStore&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InMemoryDocumentStore&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;InMemoryDocumentStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyStore&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyStore&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;documentStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;InMemoryDocumentStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;LogProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;BuildLogger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PartyStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;());&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The fixture creates instances of all classes needed, including all required
dependencies, such as the PartyStore and the test double InMemoryDocumentStore.
Should the number of dependencies change, you only have a single place to modify
here.&lt;/p&gt;

&lt;p&gt;The test creates the fixture in the constructor. This makes sure we don’t have
any shared mutable state.&lt;/p&gt;

&lt;h2 id=&quot;test-data-and-test-data-builders&quot;&gt;Test data and Test Data Builders&lt;/h2&gt;

&lt;p&gt;One of the techniques that I find most valuable in unit testing is the use of
Test Data Builders. There are libraries to help you to build test data, such as
AutoFixture, but I tend to create my test data by hand.&lt;/p&gt;

&lt;p&gt;I make a distinction between &lt;strong&gt;Test Data&lt;/strong&gt;, which is a collection of re-usable
values that I can use during test data building, and real &lt;strong&gt;Test Data
Builders&lt;/strong&gt;, which create new instances of classes for me. The test data builders
create new instances every time called so you can manipulate these instances
where needed.&lt;/p&gt;

&lt;p&gt;The instances created by the test data builder should be valid:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Most of the time, you need valid data to work with.&lt;/li&gt;
  &lt;li&gt;What is valid data evolves over time, as rules are added / removed. If you
have to turn invalid data into valid data in every unit test, your tests
become really brittle.&lt;/li&gt;
  &lt;li&gt;Turning valid data into invalid data usually is simple.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pattern I’m following in my Tests is that I call the test data &lt;strong&gt;‘The’&lt;/strong&gt;,
and the test data builder &lt;strong&gt;‘Some’&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;/// The test data creates new instances of classes to test with. &lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestDataBuilder&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;readonly&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;TestData&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestDataBuilder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TestData&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;the&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// Create a VALID instance of a party. It's easy to turn&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// a valid instance in an invalid one but most tests actually work&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// with valid data. So, start from a VALID instance and work&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// from there. &lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Party&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PartyId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PartyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PartyDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Attendees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PresentAttendees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A couple of rules I’m following for test data builders.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Test Data builders create new instances only. You can then safely manipulate
the instances as needed.&lt;/li&gt;
  &lt;li&gt;Test Data Builders should only create &lt;strong&gt;Test Data&lt;/strong&gt;, such as commands,
queries, events and other types of data holders. Don’t create other types of
classes here, such as loggers, controllers, etc. Use &lt;strong&gt;fixtures&lt;/strong&gt; for those.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TestData&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyId&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyId&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Guid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;NewGuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyName&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Organizer&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Organizer&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attendee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AttendeePresentJohn&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attendee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AttendeePresentCatherine&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attendee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AttendeeAbsentAlice&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attendee&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AttendeeAnnoyingAnton&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;IReadOnlyCollection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attendee&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PresentAttendees&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyDate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyDate&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyDate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CurrentDateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyLocation&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Location&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyLocation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()));&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;TestData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;PresentAttendees&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AttendeePresentJohn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AttendeePresentCatherine&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;///  Always control the current time in your unit&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// tests. This way, you can easily time travel&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DateTime&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CurrentDateTime&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DateTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;


    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// This method is a little trick. It returns the&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// name of the calling property, but then in snake case&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// and surrounded by hashtags. This makes it&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// immediately clear when observing the data that the value&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// actually IS the expected property, and no more and no less.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;param name=&quot;attribute&quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CallerMemberName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&quot;#&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attribute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToSnakeCase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;#&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;Test Data is mutable. This is an easy way to control what data is created by
your test data builder.&lt;/li&gt;
  &lt;li&gt;Use the data created by the test data builder and test data in your
assertions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve found that, while autofixture or Faker can sometimes generate more
realistic test data, it’s not realism i’m looking for, it’s predictability. So,
for properties where I really don’t care what the value is, i’m using a helper
method that uses the name of the property to build a value. IE:
AttendeePresentJohn =&amp;gt; #attendee_present_john#&lt;/p&gt;

&lt;h2 id=&quot;with-syntax&quot;&gt;With syntax&lt;/h2&gt;

&lt;p&gt;Within your unit tests, you have the need to control the values that you’ve just
built. In the party example, I would like to be able to change the name or the
number of attendees. I find the &lt;strong&gt;with&lt;/strong&gt; syntax very valuable for this.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;One_person_does_not_make_a_fun_party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;party&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;with&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;Attendees&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AttendeePresentJohn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;IsFun&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Should&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;BeFalse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach has several benefits:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;It’s &lt;strong&gt;immediately clear&lt;/strong&gt; what business rule i’m testing here. All the other
properties (name, location, time, etc..) are completely irrelevant here. The
only thing you see is the actual business rule.&lt;/li&gt;
  &lt;li&gt;I don’t need to &lt;strong&gt;repeat myself&lt;/strong&gt; with all other properties. I’ve seen soo
many times that the complete definition of a test data is repeated over and
over again in each unit test. This makes adding a new property a real
challenge.&lt;/li&gt;
  &lt;li&gt;Your test is very &lt;strong&gt;anti-fragile&lt;/strong&gt;. If the definition of what &lt;strong&gt;other&lt;/strong&gt;
characteristics that make a fun party ever changes, then this test will keep
working.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I sometimes see people create huge test data builders, with specialized
extensions for each property they want to manipulate. The problem of this
approach is that it requires a lot of coding to build this, whereas the language
can just accomodate this .&lt;/p&gt;

&lt;p&gt;I hope you can see how this pattern improves maintainability of tests.&lt;/p&gt;

&lt;h3 id=&quot;with-syntax-before-records&quot;&gt;With syntax before records&lt;/h3&gt;

&lt;p&gt;Before records came to c#, I used a simple extension method for this. It doesn’t
work with immutable data unfortunately but the resulting syntax works just as
well.&lt;/p&gt;

&lt;div class=&quot;language-c# highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ObjectWithExtensions&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;With&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nf&quot;&gt;doAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;party&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;With&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;PartyName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;different&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;assert-big-not-small&quot;&gt;Assert big, not small&lt;/h2&gt;

&lt;p&gt;When it comes to asserting things in tests, I often see people writing long lines of assertions, 
where each property is asserted separately.&lt;/p&gt;

&lt;p&gt;I very much recommend against this. While it seems very precise, the problem comes when you are 
maintaining your software. Adding a property will NOT break your tests, so developers often 
forget to add the property. You now have a blind spot in your test, which makes your tests
less likely to catch issues.&lt;/p&gt;

&lt;p&gt;When you have to change the definition of your class, you now also have to modify several tests, 
because each test has assertions for each property. If you have to change many tests to do a change, 
you are also undermining the reliability of your tests.&lt;/p&gt;

&lt;p&gt;My recommendation is usually:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Either be very focussed on your assertions&lt;/li&gt;
  &lt;li&gt;OR assert against a known OK object (which is then created by a test data builder)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now this is not always possible or practical (for example, when you have non-deterministically generated
values in your code) but it’s a good thing to strive for.&lt;/p&gt;

&lt;p&gt;Here’s a (little contrived) example:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Fact&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Task&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Can_save_new_party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;party&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Save&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;kt&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;saved&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PartyStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;The&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PartyId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;saved&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Should&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;BeEquivalentTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;party&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’m not asserting that the individual property values are valid. Instead, I’m asserting against 
an expected result object. In this case, it’s really simple, because the shape is the same between 
the input / output.&lt;/p&gt;

&lt;p&gt;When the shape is not the same, this is where a the &lt;strong&gt;Test Data&lt;/strong&gt; from the previous paragraph shines.&lt;/p&gt;

&lt;p&gt;Two objects, created by different methods on the Test Data Builder will generate the same ‘logical’
output value.&lt;/p&gt;

&lt;h3 id=&quot;non-deterministic-values&quot;&gt;non-deterministic values&lt;/h3&gt;
&lt;p&gt;Handling non-deterministically generated values is a bit of a challenge. Some assertion frameworks (such 
as fluent assertions or Verify) have methods to compensate for this.&lt;/p&gt;

&lt;p&gt;Another approach is to see if you can design your software to make the generation of your data 
deterministically, either by using a deterministic data generator in the actual code, or by injecting
deterministic generation for your tests only.&lt;/p&gt;

&lt;p&gt;Controlling Datetime.Now in your tests is also a really important aspect (I’ll go more into that topic in a future blogpost)
but if you control what &lt;strong&gt;now&lt;/strong&gt; means to your code, it makes the output of your tests soo much more deterministic.&lt;/p&gt;

&lt;h2 id=&quot;logging-in-unit-tests&quot;&gt;Logging in unit tests.&lt;/h2&gt;

&lt;p&gt;The last thing I’d like to address is logging in unit tests.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In .Net, the default way how you add logging is to add ILogger&lt;T&gt; as a
dependency in most of our classes. This approach has pro's and cons, which i'm
not going to go into in this post. This does mean, that every class that wants
to do logging, now requires an ILogger as dependency.&lt;/T&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The way people mostly analyze problems in production is by adding logging to
their system. Debugging in production is often not possible, so the logs are the
only way you can analyze a problem.&lt;/p&gt;

&lt;p&gt;If logs are very important to analyze a problem in production, why not use them
to analyze problems in your unit tests? I often see people inject a NullLogger
into their classes when testing. This is such a wasted opportunity. By writing
the log output to a console (or in my case, the ITestOutputHelper from XUnit), I
get a detailed log for everything that happened in my tests.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;One of the least fun things is when you have a test that succeeds locally, but
fails on the build server. Having detailed log output from your test can mean
all the difference.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To get log output in my unit tests, I typically use a
&lt;a href=&quot;https://gist.github.com/Erwinvandervalk/89fda5ba57f10ac3a5d22f26a5c42ca8&quot;&gt;TestLoggerProvider&lt;/a&gt;,
which simply pipes log output to XUnit ITestOutputHelper. Then I add a couple of
tricks, such as, change the output format to be more helpful for me, such as
printing the elapsed time, not the date time (which is not very valuable) or
pretty printing exceptions with all properties.&lt;/p&gt;

&lt;p&gt;The benefit of using XUnit ITestOutputHelper is that all output is correlated to
a test. If you simply write using Console.Write and or a Static Logger, then
your test output is not correlated with a specific test.&lt;/p&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;I’ve given several patterns that I’m using over and over again in my unit tests.
I’ve found these practices to greatly improve the maintainability of my tests
and improve the speed at which I can develop software. So I hope they help you
as well.&lt;/p&gt;</content><author><name></name></author><category term="unit-testing," /><category term="practices" /><summary type="html">In my previous post, I expressed some characteristics of well written tests. In this post, i’d like to show some techniques to help achieve these characteristics. In a future post, I’ll try to focus more on techniques and patterns to avoid.</summary></entry><entry><title type="html">Testing Small or Testing Big</title><link href="https://erwin.vandervalk.pro/test-small-or-big/" rel="alternate" type="text/html" title="Testing Small or Testing Big" /><published>2021-11-15T08:47:57+00:00</published><updated>2021-11-15T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/test-small-or-big</id><content type="html" xml:base="https://erwin.vandervalk.pro/test-small-or-big/">&lt;p&gt;A challenge I find when designing my testing strategy is at what level should
you test? Do you &lt;strong&gt;test each class individually&lt;/strong&gt; or do you group classes together
into components and &lt;strong&gt;test the api boundaries&lt;/strong&gt; of these components? The challenge
here is of course, the bigger the scope of your tests, the more meaningful (and
I would argue valuable) they become, but also the more difficult certain edge
cases are to test.&lt;/p&gt;

&lt;p&gt;This seems to be a bit of a dichotomy. Test bigger or test smaller?&lt;/p&gt;

&lt;p&gt;The thing is, &lt;strong&gt;don’t pick at all!&lt;/strong&gt; Use the best style of tests but deviate
from it for cases where it doesn’t. Be pragmatic!&lt;/p&gt;

&lt;p&gt;I usually build LOB applications, which means that I need to pass lots of data
around. Ingesting data in HTTP based or message based api’s, processing,
validating and storing the data. Then producing forms of this data again, either
as published events or on demand (http based queries).&lt;/p&gt;

&lt;p&gt;Usually, I end up with several types of classes in my system:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Functional classes.&lt;/strong&gt; These may include contracts (mapping to api’s, database
schemas, event type definitions, etc) but also the classes that operate on
them to ingest, manipulate, validate and store the data in the database.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Supporting or technical classes.&lt;/strong&gt; These can be helpers to make programming
easier, or a narrow technical solution (logging, caching, authentication,
etc..).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;focussing-on-data-flow-for-functional-tests&quot;&gt;Focussing on data flow for functional tests&lt;/h3&gt;

&lt;p&gt;For the functional classes, I try to focus on data flow through the system. That
means, modeling the actions users take and to observe the side effects.&lt;/p&gt;

&lt;p&gt;If you’re using CQRS, a great place to do more ‘functional’ style testing is at
the command / query level. A command / query is a great way to express intent
and observe side effects. Writing these tests using a BDD style pattern
(Given-When-Then) also seems to be a great fit, but with a focus on observable
outcomes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Given system in state X) When the user does X (ie: save some data), the system
does Y (store the data), which you can observe by (result of action / performing
queries / observing messages).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ideally, I prepare the current state of my system using commands and I try to
observe the outcome using queries. The reasoning is two fold:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;I can more easily &lt;strong&gt;change the inner implementation&lt;/strong&gt; without having to change my
tests.&lt;/li&gt;
  &lt;li&gt;I can create &lt;strong&gt;re-usable testing components&lt;/strong&gt; to create the commands. This means
that as my commands evolve over time, my tests naturally evolve with them,
resulting in more stable test suites.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So ideally, I will not observe that a row was added to a database (which couples
your test to your specific database implementation), but by observing the thing
the user can actually see (executing queries).&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When building event sourced applications I usually ALSO write most of my
business logic tests using the form: Given(Events), When (command),
Then(Events). Combined with other test that listen for evens (Projections,
reactors, etc.). The combination of both API based tests and more business
logic tests absolutely kicks ass!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now, some scenario’s are bigger than a single command / query, and those are
usually a good place to do at the highest (api) level.&lt;/p&gt;

&lt;h3 id=&quot;testing-value-objects&quot;&gt;Testing Value objects&lt;/h3&gt;

&lt;p&gt;Value objects (in domain driven design) usually provide a specific set of
functionality.&lt;/p&gt;

&lt;p&gt;Some are so simple (just a wrapper around a value) that they don’t need any form
of tests. By all means, don’t write tests for them then. They will be tested as
part of the regular flow.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;I usually don’t test constructors, properties, etc in isolation. An issue here
will quickly be found as part of my more functional business flows. Tests that
focus on constructors or individual properties are usually very mechanical and
don’t provide any real value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, sometimes you have value objects that do provide specific
functionality. If you have specialized &lt;strong&gt;formatting and parsing&lt;/strong&gt; logic,
specialized &lt;strong&gt;equality operations&lt;/strong&gt; or specialized &lt;strong&gt;arithmetic&lt;/strong&gt; operations,
then writing tests for them makes a lot of sense.&lt;/p&gt;

&lt;p&gt;But if you’re just relying on the c# record equality, parse using .net framework
primitives (Guid.Parse, Datetime.Parse, etc), or no specialized aritmetic, what
benefits do your tests bring? You’re probably just testing that the .Net
framework still works.&lt;/p&gt;

&lt;h3 id=&quot;isolate-technical-classes-from-functional-classes&quot;&gt;Isolate technical classes from functional classes&lt;/h3&gt;

&lt;p&gt;There are a lot of classes that don’t really provide much functional benefit but
do provide a good technical service.&lt;/p&gt;

&lt;p&gt;Sometimes, these are helpers, that make repetitive code more maintainable, or
they provide important non-functional benefits, such as authentication, caching,
logging, etc.&lt;/p&gt;

&lt;p&gt;It can be very useful to write good (old) unit tests focussing on one (or a
small set) of classes for these technical supporting classes.&lt;/p&gt;

&lt;p&gt;In the functional test cases, I do my best NOT to have to mock out these classes
but just include them in my testing flow.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In fact, including techncal classes in your functional test cases can
interesting scenario’s. IE: If you have caching enabled, can the user observe
the changes you’ve just made or do you need some form of cache busting or
checks for eventual consistency?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;but-but-but-i-have-some-cases-that-are-not-easily-tested-with-the-examples-above&quot;&gt;But, but, but.. I have some cases that are not easily tested with the examples above.&lt;/h3&gt;

&lt;p&gt;Great, we all do. If you have certain edge cases that are both &lt;strong&gt;imporant&lt;/strong&gt; to
test but also &lt;strong&gt;difficult&lt;/strong&gt; to test at api / component levels, then these are a
great candidate to test in isolation. Ideally, I’d write my classes to minimize
the need to do any form of mocking, but sometimes you just don’t have a choice.
In that case, go for it.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Not all edge cases are worth testing. Consider if the cost of writing /
maintaining the test outweighs the benefits. If it does, great, do it! If it
doesn’t, just skip it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;

&lt;p&gt;This heuristic has helped me a lot to write tests that are both maintainable, 
readable and very stable. I hope they help you as well.&lt;/p&gt;</content><author><name></name></author><category term="unit-testing," /><category term="practices" /><summary type="html">A challenge I find when designing my testing strategy is at what level should you test? Do you test each class individually or do you group classes together into components and test the api boundaries of these components? The challenge here is of course, the bigger the scope of your tests, the more meaningful (and I would argue valuable) they become, but also the more difficult certain edge cases are to test.</summary></entry><entry><title type="html">Welcome</title><link href="https://erwin.vandervalk.pro/welcome/" rel="alternate" type="text/html" title="Welcome" /><published>2021-11-10T08:47:57+00:00</published><updated>2021-11-10T08:47:57+00:00</updated><id>https://erwin.vandervalk.pro/welcome</id><content type="html" xml:base="https://erwin.vandervalk.pro/welcome/">&lt;p&gt;Welcome to my new and revamped blog.&lt;/p&gt;

&lt;p&gt;Many years ago, I used to occasionally blog. About things that I thought would be valuable for me to remember and perhaps would be valuable for other people as well.&lt;/p&gt;

&lt;p&gt;Now I never liked the blogging platform I used to use (blogger.com) and that was a big barrier for me to keep doing it. Now, i’ve moved to a github pages based blog. Let’s see, hopefully i’ll be able to keep it up and write about things that might interest you as well.&lt;/p&gt;</content><author><name></name></author><category term="frist" /><summary type="html">Welcome to my new and revamped blog.</summary></entry></feed>