DEV Community

Discussion on: Unit testing NestJS with mongo in memory...

Collapse
 
robsonpca01 profile image
Robson Carvalho

Good article! In my scenario, i have two services, each with its own schema, but both schemas have relationship with each other, do you have any suggestion about how can i setup this tests? I just want to use mongoose populate function to get the related data.

thnks!

Collapse
 
bassochette profile image
Julien Prugne

Using an in-memory MongoDB will not change the behavior of mongoose. Therefore, if the link data are seeded in the database you will be able to use the populate method.

Now what you might struggle with is: How to seed?
I see to path for you:

1: use the services.
they need to be available as providers in your testingModule.
The caveat here is: you won't be able to test independently both services.

2: get the models from the testingModule

You'll be able to bypass any logic and just add data for your test.
The caveat here: you are bypassing all business logic...

here is a little example:

import { Test, TestingModule } from '@nestjs/testing';
import { MongooseModule } from '@nestjs/mongoose';
import { Model } from 'mongoose';

import { IngredientDocument } from 'path to the interface or class';
import { RecipeDocument } from 'path to the interface or class';
import { IngredientSchema } from 'path to the schema';
import { RecipeSchema } from 'path to the schema';

import { RecipeService } from 'path to the recipe service';

describe('RecipeService', () => {
  let recipeService: RecipeService;

  let testingModule: TestingModule;

  let ingredientModel: Model<IngredientDocument>;
  let recipeModel: Model<RecipeDocument>;

  beforeEach(async () => {
    testingModule = await Test.createTestingModule({
      imports: [
        rootMongooseTestModule(),
        MongooseModule.forFeature([

          // use the same model name as you declared them in your module

          { name: 'Recipe', schema: RecipeSchema },
          { name: 'Ingredient', schema: IngredientSchema },
        ]),
      ],
      providers: [RecipeService],
    }).compile();

    recipeService = testingModule.get<RecipeService>(RecipeService);

    // The string to get the model is: 'token used as name in Mongoose.forFeature' + 'Model'
    recipeModel = testingModule.get<Model<RecipeDocument>>(
      'RecipeModel',
    );

    // The string to get the model is: 'token used as name in Mongoose.forFeature' + 'Model'
    ingredientModel = testigModel.get<Model<IngredientDocument>>(
      'IngredientModel',
    );
  });

  afterAll(async () => {
    await closeInMongodConnection();
  });

  afterEach(async () => {
    await recipeModel.deleteMany({});
    await ingredientModel.deleteMany({});
  });

  it('should be defined', () => {
    expect(recipeService).toBeDefined();
  });

  // write your test here

});

Enter fullscreen mode Exit fullscreen mode

hoping this will help you start :)