I recently changed from
Jest. Pretty lovely experiences. It took a while to figure out the right way to test an express route, but when it works, it works like a charm. I share my experiences here, hope it helps. I love jest assertion function more than
Chai, seems more concise to me.
You need to install
The reason behind this is that it won’t listen to the port after testing.
This is your
Then you can start your server via
node server.js, and you can import that
app.js for testing.
Jest test will end when it hits the last line of the test function, so you need to use a
done() to make it right.
done is not a must, the following one is more neat.
Two Things to be noticed here:
returnis crucial, otherwise your tests will get stuck.
- No need to pass
doneto your test.
It’s good to see that my beloved
Does the imperative programming style and synchronous looking make you feel happy? :D Two things also be noticed here.
asyncto the function before you want to use
- You need the
babel-preset-envpackage to use this.
- You don’t need to use
babel-preset-envif you use Node8 or above because it’s supported.
Supertest way is still available. You just need to
return the statement and remember not use
.end() and the end.
Thanks Adam Beres-Deak for the hint!
A working example is as the following:
Notice that without that
return, the test will always pass.
You need to handle the database connection through the tests. In my case, I used this pattern:
Here I use mongoDB. I will connect at the beginning of this test suite, and disconnect at the end. And the
mongoDB just a wrapper class.
You may consider using
afterEach to manage the database connection to prevent race condition. More explanation below.
done? It is a variable used to indicate that an async operation is finished.
Jest will give that as a parameter for that
You might want to use
jest --runInBand to run the tests depending on how you structure your tests. Otherwise, multiple tests access same collection will cause random failing for your tests.
But thanks to one of the readers,
Melroy van den Berg, I think you don’t need
--runInBand if you open and close database connection with
afterEach rather than the
afterAll. Not tested, but it should be the root cause of the problem that I was encountering previously!
Why? Because when you try to test CRUD against the same record for same collection with the same database connection, of course you will encounter race condition. Even though this is something that won’t happen in production time.
And when you simply open new connection for each test, then this race condition problem will be solved naturally in the database layer.
And why do we need to worry about how many database connection we are opening during test time?! :D
But if your machine can’t handle it. Then feel free to maintain database connection in a test suite basis. Nothing wrong with that, your tests are still isolated if you done it right. And manage database connection is a test basis won’t promise the isolation of tests, it’s a different problem.
That’s all, hope it help. :)