
Lesson Description
The "Connecting to the Test Database" Lesson is part of the full, Complete Go for Professional Developers course featured in this preview video. Here's what you'd learn in this lesson:
Melkey creates a new store to connect to the test database. The test database is running on a separate port. The setupTestDB function connects to the database, runs the migrations, and truncates the tables; the rows are cleared out each time the tests run.
Transcript from the "Connecting to the Test Database" Lesson
[00:00:00]
>> Melkey: In the store folder, we're gonna make a new file called workout_store_test.go and the test append at the end is specific. We need to actually have that to let the built-in tester and go, and identify this file is going to be used for testing purposes. So let's go ahead and build this.
[00:00:20]
It's gonna be in package store, and it's gonna be a few things we need to actually initially bring in. So there's this really good package that I need to share with you guys, it is called stretcher testify, if I will go out in a limb here and say if you've done any form of testing and go, you have used this package.
[00:00:41]
It is like the industry standard for testing in go. As you can see, it's 24.1 1000 get up stars, it's a great tool kit, it's used by just a lot of people. And like I said, it's the golden standard to use within go, right? And it allows us to have a bunch of these really nice function utilities to assert different values in our testing cases.
[00:01:04]
So you can see here, do these values equal? Do they not equal? Is it nil? Do I expect an error, etc, etc, and also give us this little, nice mock thing that hopefully we can also explore. So with that, let's go ahead and install testify. So if you want go back to terminal, go to any empty terminal that you have in the root of our project.
[00:01:28]
>> Melkey: Okay, and then what we can do is just install, let me just see, right here. Go get github.com/stretcher/testify. And it's a go get, we don't have to do go install. We don't need it to be binded to our bin or our path cuz it's not any native commands we're gonna be using that testify offers, all right?
[00:01:53]
So with all that said, we are going to first build a helper function for us to connect to our test database, okay? Now, just as a reminder, the test database, we should never touch this test database outside of this file, like ever. This is a database that we are gonna use, and there's action argument to be made in the Docker Compose, you can separate them.
[00:02:15]
You can have one Docker Compose to run your local DB and another Docker Compose to run your test DB. So that you're not running two DBs at once. I did it here just to kind of save a file and have it one, but if you want, you could have two separate DBs running.
[00:02:28]
Let it have your local DB and just have the test DB running for when you run this test suite. And the purpose of this test suite, it's a bit of this blur line between a mock like a unit test and like an integration test, because we're truly going to be calling and querying our database.
[00:02:45]
And because of that, what I call these unit tests, I'll call them more unit tests than integration tests. Even though we are integrating with a database, my definition for integration test is a full end-to-end test suite that involves multiple different services across the scope of your application. But again, these are just my definitions and my approach to this one topic.
[00:03:09]
That's enough talking, let's go ahead and write some code. So here, the first thing I wanna write is func, I'm gonna set up testDB, like so, and this is gonna take an argument that we haven't seen before to be a pointer to testing.T, all right? And testing, we're gonna import it is a standard package in the Go library, and it provides us testing fixtures that make testing very, very easy in go, all right?
[00:03:36]
And what this is going to return is a SQL database like so. [COUGH] And we're gonna do is dB error. We're gonna make the same connection string, connection string, so we can do open, okay? Here we can bring in pgx. And to do this, we can also bring back the same import from Jack cpgx.
[00:03:58]
So in the import, go ahead and just import github.com/jackcpgx before standard lib. This is already an import that we saw in database.go, all right? And the second argument in the SQL open is the actual connection string. So here, we can do host=local host, users gonna be postgres, okay?
[00:04:19]
The password is also going to be postgres, we'll have the DB name equal to postgres and then the important part is the port. So my port is 5433, okay? And this is from my test database, my real database is running on 5432, just try and make that clear.
[00:04:38]
And we'll do SSL mode equals disable, like so. Let's always check the errors. If our error does not equal to nil, we're actually not going to return an error, we're actually going use our texting fixture and do a fatal. And we'll say, opening test DB, we can just put db here as the error like so.
[00:05:03]
NT fail covers any return, so we don't need to explicit rate return at the end of this it's going to complete fail or test case. So here, we want to run the migrations for our test dB, okay? And the way we can do this is pretty simple, we can do error.
[00:05:20]
We can just say, migrate, not Fs, just migrate. We're passing that dB, and then here we're gonna pass in the path to migrations from where we are relative. So it's just gonna be two folders up. And you can see we have migrations over here, like so.
>> Melkey: If our error does not equal to nil, what I wanna do is just again, do a t.Fatalf, t.Fatal format, okay?
[00:05:50]
I'm gonna say, migrating test dB error and slide the error inside like that, okay? And then, one other instance is, like I said, test dB, it should be a blank slate every single time you run our tests. So I wanna add a function here, and this function is basically going to truncate everything in our dB.
[00:06:12]
Now let's do backticks, so truncate, okay, workouts and workout_entry. And we'll make sure it cascades. And what this does is basically to allow us to wipe the dB every time we want to run our setup tests. And I definitely recommend doing this, it is not the most performant way, I will admit.
[00:06:33]
But the reason why I like this is, in between test suites, test functions, I don't want the test that I wrote and create workout test to potentially contaminate the tests. I want to run on update workout or get workout, delete workout. I want the dB to be absolutely empty.
[00:06:51]
I wanna insert the values, I wanna test for deletion and then delete them and make sure they fully got deleted, or for any kind of combination between the CRUD operations, okay? And then here, all we have to do is return dB, like so, or we can catch this error too, I think I forgot to do this.
[00:07:05]
So if error does not equal to nil, we can again just do T.fatal, we can say truncating tables error, like so.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops