user11068505
user11068505

Reputation:

Mocking dependency in controller unit test

The application I'm working on uses Nest framework. I am writing a unit test for a controller which has two providers: ImdbService and RabbitMQService, which I'm both attempting to mock in beforeEach() method. My issue lies in mocking the latter, this is, RabbitMQService provider.

My plan for writing a test for the controller is to either mock amqplib or test it by mocking a message, but I'm not sure which method is better. I am also completely new to testing with Jest in general.

The RabbitMQService looks like this

@Injectable()
export class RabbitMQService {
    @Inject(RABBITMQ_CONNECTION)
    protected readonly connection: RabbitMQConnection;

    get defaultConnection() {
        return this.connection;
    }
}

where type RabbitMQConnection = amqp.Connection. I have no idea on how to mock that.

Any sort of help is appreciated.

Upvotes: 2

Views: 1735

Answers (1)

A. Maitre
A. Maitre

Reputation: 3559

Your question may have been already answered (partially) here
You can refer to these links too:
- Custom providers of NestJS docs
- and testing section of NestJS docs

Still based on previous links, you can give it a try with something like this (not tested tho)

import { MessagesController } from './messages.controller';
import { RabbitMQService } from './rabbitmq.service';
import { RabbitMQConnection } from './somewhere';

describe('MessagesController', () => {
  let messagesController: MessagesController;
  let rabbitMqService: RabbitMQService;
  let mockRabbitMQConnection = {
      /* mock RabbitMQConnection implementation
      ...
      */
      // e.g. it could be:
      defaultConnection: (): RabbitMQConnection => { 
        //... TODO some attributes / functions mocks respecting RabbitMQConnection interface / type
      }
  };

  beforeEach(() => {
    const module = await Test.createTestingModule({
        controllers: [MessagesController],
        providers: [RabbitMQService],
      })
      .overrideProvider(RABBITMQ_CONNECTION)
      .useValue(mockRabbitMQConnection)
      .compile();

    rabbitMqService = module.get<RabbitMQService>(RabbitMQService);
    messagesController = module.get<MessagesController>(MessagesController);
  });

  describe('findAll', () => {
    it('should return an array of messages', async () => {
      const result = ['test'];
      jest.spyOn(rabbitMqService, 'findAll').mockImplementation(() => result); // assuming you would have some findAll function in your rabbitMqService service

      expect(await messagesController.findAll()).toBe(result);
    });
  });
});

Best would be to have a repo with minimalistic reproduction of your environment (without business logic) so that we can have a base to help you out more.

Hope this gives you a bit more of insight, even though it doesn't fully solve your problem :)

Upvotes: 1

Related Questions