title: Unit Testing Nestjs Mongoose services
body: <p>I've been trying to figure out how to unit test services NestJS.
  So I wrote a spec file which tests these NestJS services which use mongoose using jest.</p>
  
  <p>The spec file is as follows:</p>
  
  <pre class="lang-js prettyprint-override"><code>import { Test, TestingModule } from '@nestjs/testing';
  import { EventsService } from './events.service';
  import { getModelToken } from '@nestjs/mongoose';
  import { CreateEventDto } from './dto/create-event.dto';
  
  const event = {
    _id: '53d53d2s',
    name: 'Event Name',
    description: 'Description of the event.',
    min_team_size: 0,
    max_team_size: 4,
    event_price: 300,
  };
  
  describe('EventsService', () =&gt; {
    let service: EventsService;
    const eventModel = {
      save: jest.fn().mockResolvedValue(event),
      find: jest.fn().mockResolvedValue([event]),
      findOne: jest.fn().mockResolvedValue(event),
      findOneAndUpdate: jest.fn().mockResolvedValue(event),
      deleteOne: jest.fn().mockResolvedValue(true),
    };
    beforeEach(async () =&gt; {
      const module: TestingModule = await Test.createTestingModule({
        providers: [
          EventsService,
          {
            provide: getModelToken('Event'),
            useValue: eventModel,
          },
        ],
      }).compile();
  
      service = module.get&lt;EventsService&gt;(EventsService);
    });
  
    it('should return all the events', () =&gt; {
      expect(service.findAll()).resolves.toEqual([event]).catch( err =&gt; {
        console.log(err);
      });
    });
    it('should create a new event and save it', () =&gt; {
      expect(service.create({
        name: event.name,
        description: event.description,
        event_price: event.event_price,
        max_team_size: event.max_team_size,
        min_team_size: event.min_team_size
      } as CreateEventDto )).resolves.toEqual(event).catch(err =&gt; {
        console.log(err);
      });
    });
    it('should return one event', () =&gt; {
      expect(service.findOne('53d53d2s')).resolves.toEqual(event).catch(err =&gt; {
        console.log(err);
      });
    });
    it('should find and update one model', () =&gt; {
      expect(service.findOneAndUpdate('53d53d2s', {} as any)).resolves.toEqual(event).catch( err =&gt; {
        console.log(err);
      });
    });
    it('should delete one model', () =&gt; {
      expect(service.deleteOne('53d53d2s')).resolves.toBeTruthy().catch( err =&gt; {
        console.log(err);
      });
    });
  });
  </code></pre>
  
  <p>This is the service file:</p>
  
  <pre class="lang-js prettyprint-override"><code>import { Injectable } from '@nestjs/common';
  import { Model } from 'mongoose';
  import { CreateEventDto } from './dto/create-event.dto';
  import { EventInterface } from './interfaces/event.interface';
  import { InjectModel } from '@nestjs/mongoose';
  
  @Injectable()
  export class EventsService {
    constructor(@InjectModel('Event') private readonly eventModel: Model&lt;EventInterface&gt;) {}
  
    async create(createEventDto: CreateEventDto): Promise&lt;EventInterface&gt; {
      const createdEvent = new this.eventModel(createEventDto);
      return createdEvent.save();
    }
  
    async findAll(): Promise&lt;EventInterface[]&gt; {
      return this.eventModel.find();
    }
  
    async findOne(id): Promise&lt;EventInterface&gt; {
      return this.eventModel.findOne({ _id: id });
    }
  
    async findOneAndUpdate(id, createEventDTO: CreateEventDto): Promise&lt;EventInterface&gt; {
      return this.eventModel.findOneAndUpdate({ _id: id }, createEventDTO);
    }
    async deleteOne(id): Promise&lt;any&gt; {
      return this.eventModel.deleteOne({ _id: id});
    }
  }
  </code></pre>
  
  <p>Here all tests past successfully except the <code>create()</code>. It shows the following error:
  <code>{ Error: expect(received).resolves.toEqual()</code></p>
  
  <pre class="lang-sh prettyprint-override"><code>Received promise rejected instead of resolved
  Rejected to value: [TypeError: this.eventModel is not a constructor]
      at expect (/home/rakesh/SJPUC/Equinox-2019/equinox-api/node_modules/expect/build/index.js:138:15)
      at Object.it (/home/rakesh/SJPUC/Equinox-2019/equinox-api/src/events/events.service.spec.ts:44:5)
      at Object.asyncJestTest (/home/rakesh/SJPUC/Equinox-2019/equinox-api/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
      at resolve (/home/rakesh/SJPUC/Equinox-2019/equinox-api/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
      at new Promise (&lt;anonymous&gt;)
      at mapper (/home/rakesh/SJPUC/Equinox-2019/equinox-api/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
      at promise.then (/home/rakesh/SJPUC/Equinox-2019/equinox-api/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
      at process._tickCallback (internal/process/next_tick.js:68:7)
    matcherResult: undefined,
  </code></pre>
  
  <p>Also, I would like to know a better way to unit test these services.</p>