skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER

    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.


  2. 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:

    1. Insert a document with createdAt value new Date() - 43195 so the expected expiration date will be in 5 seconds from now.
    2. Get the _id of the document
    3. Find the document by _id to confirm it’s been saved
    4. Wait for 2 minutes
    5. Find the document by _id to confirm it’s been deleted
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search