If the model is just plain schema, there is not much to test about. But with Mongoose, you can add instance methods and static methods which embeds lots of core logic around CRUD. You definitely wanna test this. In this blog, we will use
Jest to test
Mongoose model methods.
Of course you can unit test your model by mocking the mongoose methods. But I really don’t see the benefits of that. Yes, the CRUD part is taking care by mongoose and mongodb driver, no need to test that.
But even the data is saved perfectly into the database doesn’t mean you have saved the correct data.
Furthermore, for a bulk get, does your query give you the right result? Does your query still give you the expected result after you refactoring? This is something only integration test could tell you.
The concept here is simple:
beforeAll(): connect to database
afterAll(): database disconnect
beforeEach(): setup demo data
afterEach(): remove demo data
There is another pattern for read-only method:
beforeAll(): connect to database and prepare data
afterAll(): database disconnect and remove them
The code looks like below:
Do remeber use
done() to close the database, otherwise, you will get mad about some weird exception.
This is the most important part you need to know. And it could adopts to any testing method like unit test and acceptance test.
- Will it give us the correct result when everything is OK?
- Will it handle the abnormal case like empty result?
- Will it handle the error case?
- Will it handle the edge case?
- Will it handle some special parameter? For instance, the
limitin a bulk get API.
For the normal case:
For the abnormal case:
For the error case:
An interesting fact here: You could see that I use both
.catch() here which doesn’t make any sense. The point is:
For some important method, this tip will make sure that every error is wrapped in the normal
jesterror report rather than just throwing some error in the console. Furthermore, when dealing with promise, sometimes,
Jestwill give you some completely useless callstack which none of it is part of your code. This is how it could save your life, when the callstack is meaningless, try this.
When you try to assert an error:
Notice here you just need to
await that query since we don’t care about its result.
When you just want to assert a normal result:
If you use environment variable for testing, it’s good to test it to notify the people who run the test.
There is no
conftest.py concept in
Jest which you could run some fixtures before you run all the tests. So the above check is not enough for prevent executing some dangerous methods like a handy
removeAll(), So I add a check in that method too:
In fact, it is the tip for use
Jest in a async way.
If you just want to
save one document, just
return that promise,
Jest will handle that for you.
But when you need to save more document,
return won’t help you here. And besides promise chain, you could use fancy
That’s it, hope it helps.