I'm using MongoDB's TTL Index feature to automatically delete documents (in this case, email verification tokens) after a certain amount of time.
I also use Mongoose, which creates this index via the expires
property (on the createdAt
timestamp):
const emailVerifiationTokenSchema = new mongoose.Schema<IEmailVerificationToken>({
userId: { type: mongoose.Types.ObjectId, required: true },
email: { type: String, required: true },
tokenId: { type: String, required: true },
createdAt: { type: Date, required: true, default: () => Date.now(), expires: 43200 },
});
How can I write a test that ensures that I'm setting this value to the correct amount? There doesn't seem to be a way to access this value from the outside.
I use Jest for testing.
CodePudding user response:
First of all it won't be a unittest. It violates at least 2 rules of unittesting - don't test what you don't own, and test individual units in isolation. If you want to test TL index jest is not the best tool. Mongo triggers TTL clean up every minute, so you would need to exercise content of the database at least 1 minute after expected deletion. I would give 2. If you insist of using jest, you will need to pause it for that time which will slow down the whole test suit.
Regardless of the testing framework the test should be something like this:
- Insert a document with
createdAt
valuenew Date() - 43195
so the expected expiration date will be in 5 seconds from now. - Get the _id of the document
- Find the document by _id to confirm it's been saved
- Wait for 2 minutes
- Find the document by _id to confirm it's been deleted
CodePudding user response:
I figured it out.
Mongoose's expires
property creates a TTL index in MongoDB. We can retrieve this index over the model class by calling listIndexes
and it contains an expireAfterSeconds
property:
const emailVerificationIndexes = await EmailVerificationToken.listIndexes();
outputs something like this:
[
{
"v":2,
"key":{
"_id":1
},
"name":"_id_"
},
{
"v":2,
"key":{
"createdAt":1
},
"name":"createdAt_1",
"background":true,
"expireAfterSeconds":43200
}
]
Then we can simply assert that this property has the expected value in a unit test.