Background
Unit testing is a very important link in the process of writing code. It can effectively help us find and handle some problems as soon as possible.
When the code needs to read some data from the database or write some data to the database, things will become complicated!
There may be network failures, or the database may be shut down for maintenance. In these cases, we cannot connect to the database, which means that our code cannot run normally.
If we want to continue to write code, we need some unit tests to ensure that we are not affected by external dependencies!
Next, let's see how we can deal with this problem.
Hard To Test
Suppose we need to find the type field of a table in the database according to the ID, and then classify it according to the query results of the database.

Before we implement this method, we may write a empty method as following.
Next, we will start to write unit tests and consider some possible situations.
After finishing the unit tests, we should implement the HandleAsync method according to the flowchart, the following code is a simple implementation.
If we use dotnet test
to run the unit tests, there is no doubt that all tests fail.
![]()
Because the code depends on a real database, if we input something wrong for it, everything will be down.
How can we modify the code to make it can be tested?
Can Be Tested
we can add a parameter which type is DbConnection, so that we can pass it from the outside to the method.
When we using DbConnection, we can mock it without connect to the database.
DbMocker is a great tool that help us to mock a connection to a relational database. The core object is MockDbConnection
.
It can mock not only normal SQL execution, but also abnormal conditions.
MockDbSelect is a method for mocking a normal SQL execution, it will return a row when the command text start with select.
MockDbException is a method for mocking abnormal conditions, it will throw an exception when the command text start with select.
The implementation of Handle2Async is as following:
Run unit tests using dotnet test
and all tests will succeed.
![]()
But in real world, we may not add DbConnection for each method, it just suitable for some extension methods.
Splitting database operation and business operation can make unit tests more easier.
Easy To Test
Define a database operation interface at first.
Add a biz class that depends on above interface.
At this time, it's very easy to write unit tests.
We only need to use the simple operation of a mock object to complete the database operation.
Run unit tests using dotnet test
and all tests will succeed as well.
![]()
Summary
This article shows two ways to write unit tests for database related business code. If a method exposes parameters of type DbConnection, we can use DbMocker for simple processing. However, normal business code recommends separating logic and interface oriented programming.
I hope this will help you!