Nest: How to mock controller (Can't resolve dependency)

Created on 30 May 2019  ·  3Comments  ·  Source: nestjs/nest

Hi ,
I am getting error when I run the test case, I checked most of the sites but not getting resolve my issue. please help

● UsersController › should be defined

Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument at index [0] is available in the _RootTestModule context.

  at Injector.lookupComponentInExports (../node_modules/@nestjs/core/injector/injector.js:180:19)

● UsersController › should be defined

expect(received).toBeDefined()

Received: undefined

attack-controller-spec.ts

`import { Test, TestingModule } from '@nestjs/testing';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

describe('UsersController', () => {
let controller: UsersController;
let service: UsersService;

beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UsersController],
providers: [UsersService],
}).compile();

controller = module.get<UsersController>(UsersController);
service = module.get<UsersService>(UsersService);

});

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

user-controller.ts

`import { Controller, Inject, Get, Query, Param } from '@nestjs/common';
import { UsersService } from './users.service';
import { Users} from './interfaces/users.interface';
import { GetUsersDto } from './dto/get-users.dto';

@Controller('users')
export class UsersController {
constructor(@Inject('UsersService') private readonly usersService: UsersService) {}

@Get()
async getUsers(@Query() dto: GetAttacksDto): Promise return this.usersService.getAvailableUsers( dto.id ||'');
}

@Get(':id')
async getUsersByUserId(@Param('id') id: string): Promise return this.usersService.getAvailableUsers(id);
}
}
`

needs triage question 🙌

Most helpful comment

The problem you're encountering here is that when injecting UserService, Nest tries to resolve all of UserService's dependencies (databases, other services, etc.), so you would need to provide those in your testing module as well.

What you can do instead is mock your UserService dependency as follows

import { Test, TestingModule } from '@nestjs/testing';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

describe('UsersController', () => {
  let controller: UsersController;
  let service: UsersService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
    controllers: [UsersController],
    providers: [
      {
        provide: UsersService,
        useValue: {
          getAvailableUsers: jest.fn()
        }
      }
    ],
  }).compile();

  controller = module.get<UsersController>(UsersController);
  service = module.get<UsersService>(UsersService);
  });

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

And, as above, mock the functions of your UsersService to return what is expected as to test your controller logic. You can use this method of mocking for your service classes as well, really useful for mocking database responses :smile:

All 3 comments

The problem you're encountering here is that when injecting UserService, Nest tries to resolve all of UserService's dependencies (databases, other services, etc.), so you would need to provide those in your testing module as well.

What you can do instead is mock your UserService dependency as follows

import { Test, TestingModule } from '@nestjs/testing';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';

describe('UsersController', () => {
  let controller: UsersController;
  let service: UsersService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
    controllers: [UsersController],
    providers: [
      {
        provide: UsersService,
        useValue: {
          getAvailableUsers: jest.fn()
        }
      }
    ],
  }).compile();

  controller = module.get<UsersController>(UsersController);
  service = module.get<UsersService>(UsersService);
  });

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

And, as above, mock the functions of your UsersService to return what is expected as to test your controller logic. You can use this method of mocking for your service classes as well, really useful for mocking database responses :smile:

Thanks its working for me

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings