Unit testing with a DB server working in docker is a a lot better alternative than Sqlmock, normally
About two years in the past, I wrote an article discussing learn how to take a look at a GORM software with Sqlmock.
Time flies, and I understand that the majority builders don’t undertake this strategy (not less than on my crew). Writing a take a look at case utilizing Sqlmock is simply too advanced to get began.
The core challenge is that you could write up the entire SQL snippet manually, then evaluate it with the output from GORM. This workload is already far more than writing the codes to be examined. In spite of everything, the rationale we use GORM is to keep away from writing uncooked SQL manually.
We have to discover a higher method.
On the whole, testing DB software is tough. The primary cause is the database server itself.
- If the dev crew shares a distant database server, then information battle is inevitable.
- If we create accounts for each developer on this database server, then unit exams ought to be run with totally different accounts. And somebody wants to take care of these accounts.
- If we demand each developer set up and arrange a database server on their native workstation, we improve the issue of establishing a improvement setting.
Appears there’s no reply is nice sufficient. But when we might run the database server regionally with docker and combine the take a look at case with docker, that will be good.
Picture course of under:
- Begin a database server with docker earlier than every take a look at suite. open a GORM connection to this server
- Earlier than each take a look at case runs, clear information within the database and re-create tables if wanted
- Run all take a look at instances
- Cease the database server after take a look at suite execution

In principle, we might management the docker daemon with a command line. However with the assistance of dockertest, this goal might be achieved simply.
Right here’s a step-by-step tutorial for unit testing a GORM software with an actual database server working in docker.
we’ll re-use the instance software within the earlier article. You’ll find the supply code on Github.

We take Postgres for example on this article, nevertheless it might work with every other database.
Establishing take a look at suite
In keeping with the sequence diagram, we do a collection of preparations:
- In
BeforeSuite
, we create an occasion of*gorm.DB
and a operate to scrub up docker assets. The operatesetupGormWithDocker
will likely be defined later - In
AfterSuite
, we namecleanupDocker
to launch docker-related assets. - In
BeforeEach
, we drop the default schema after which re-create it to verify the database is clear and prepared earlier than each take a look at case run.
Beneath are the reasons for the core operate setupGormWithDocker
:
- Create a docker useful resource pool with
dockertest.NewPool
, which is used to run the docker container - Specify picture identify, picture model, and setting variable with
dockertest.RunOptions
fnConfig
is a operate to regulate bootstrap coverage. On this case, we want the docker container to be auto-removed after cease and by no means auto-restart- We use
pool.RunWithOptions
to run the container, then create the cleanup operatefnCleanup.
- Since it should take a while to begin the container, we have to wait till the container is prepared. Solely after that, we will return the
*gorm.DB
occasion. Right here,pool.Retry
involves the rescue.pool.Retry
will execute the parameter operate repeatedly till the operate returnsnil
(which implies the container is prepared)
Constructing take a look at case
With the preparations within the take a look at suite, we might get a usable occasion of *gorm.DB
, connecting to an area database server, and the database will likely be cleared earlier than each take a look at case execution.
- In
BeforeEach
we create an occasion ofRepository
for testing. Callingrepo.Migrate
to create tables robotically, then create pattern weblog information. - The take a look at instances are fairly intuitive. We name the repo strategies, and confirm the anticipated result’s returned. There is no mock right here since we’re utilizing an actual database server.
- In comparison with Sqlmock, there’s no want to jot down uncooked SQL manually, and we might end your entire take a look at case in lower than 100 strains of code.
- dockertest will pull photos if vital, however with out a obtain progress immediate. Our suggestion is to run
docker pull postgres:14
earlier than working the take a look at case for the primary time. - Working the take a look at suite might take a number of seconds since we have to begin up the Postgres database server. It could really feel slower than most in-memory unit-test, however it’s acceptable.
- Throughout
pool.Retry
, some connection errors will likely be output. If you happen to don’t just like the disturbance, cross&gorm.ConfigLogger: logger.Default.LogMode(logger.Silent)
togorm.Open
to shut log - Your software might rely on some Postgres extension. On this case, you possibly can exchange the usual Postgres picture with a customized one. For instance, if you happen to want postgres all, you could possibly use this docker image
- Testing the GORM software towards an actual database server has an enormous benefit.
- With the assistance of
dockertest
, an area docker container might work with golang unit testing seamlessly. - In contrast to
Sqlmock
, all of the DB logics are working on an actual database server, there’s no want for any mock, and take a look at instances are considerably simplified. - Is there any cause to stay with Sqlmock now?
- For the entire supply code, please go to its repository.
Cheers!