NarHakobyan / awesome-nest-boilerplate

Awesome NestJS Boilerplate 😍, Typescript 💪, Postgres 🎉, TypeORM 🥳
https://narhakobyan.github.io/awesome-nest-boilerplate
MIT License
2.39k stars 451 forks source link

AuthController unit test not working #307

Open SaadBazaz opened 1 year ago

SaadBazaz commented 1 year ago

After running NODE_ENV=development yarn test, I get:

yarn run v1.22.19
$ NODE_ENV=test jest
 FAIL  src/modules/auth/auth.controller.spec.ts (134.169 s)
  AuthController
    root
      ✕ should return "http://localhost" (1 ms)

  ● AuthController › root › should return "http://localhost"

    Nest can't resolve dependencies of the AuthController (?, AuthService). Please make sure that the argument UserService at index [0] is available in the RootTestModule context.

    Potential solutions:
    - Is RootTestModule a valid NestJS module?
    - If UserService is a provider, is it part of the current RootTestModule?
    - If UserService is exported from a separate @Module, is that module imported within RootTestModule?
      @Module({
        imports: [ /* the Module containing UserService */ ]
      })

       8 |
       9 |   beforeAll(async () => {
    > 10 |     app = await Test.createTestingModule({
         |           ^
      11 |       controllers: [AuthController],
      12 |       providers: [],
      13 |       imports: [],

      at TestingInjector.lookupComponentInParentModules (../node_modules/@nestjs/core/injector/injector.js:241:19)
      at TestingInjector.resolveComponentInstance (../node_modules/@nestjs/core/injector/injector.js:194:33)
      at TestingInjector.resolveComponentInstance (../node_modules/@nestjs/testing/testing-injector.js:16:45)
      at resolveParam (../node_modules/@nestjs/core/injector/injector.js:116:38)
          at async Promise.all (index 0)
      at TestingInjector.resolveConstructorParams (../node_modules/@nestjs/core/injector/injector.js:131:27)
      at TestingInjector.loadInstance (../node_modules/@nestjs/core/injector/injector.js:57:13)
      at TestingInjector.loadController (../node_modules/@nestjs/core/injector/injector.js:75:9)
          at async Promise.all (index 0)
      at TestingInstanceLoader.createInstancesOfControllers (../node_modules/@nestjs/core/injector/instance-loader.js:56:9)
      at ../node_modules/@nestjs/core/injector/instance-loader.js:34:13
          at async Promise.all (index 1)
      at TestingInstanceLoader.createInstances (../node_modules/@nestjs/core/injector/instance-loader.js:31:9)
      at TestingInstanceLoader.createInstancesOfDependencies (../node_modules/@nestjs/core/injector/instance-loader.js:21:9)
      at TestingInstanceLoader.createInstancesOfDependencies (../node_modules/@nestjs/testing/testing-instance-loader.js:14:9)
      at TestingModuleBuilder.compile (../node_modules/@nestjs/testing/testing-module.builder.js:47:9)
      at Object.<anonymous> (modules/auth/auth.controller.spec.ts:10:11)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        134.283 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Any ideas on why this isn't working would be appreciated. Kind of a newbie in NestJS testing.

spotlesscoder commented 1 year ago

The providers that the controller depends on are not specified. I suggest mocking them this way (note that I also changed the test itself to make it actually work)

import type { TestingModule } from '@nestjs/testing';
import { Test } from '@nestjs/testing';

import { UserEntity } from '../user/user.entity';
import { UserService } from '../user/user.service';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { TokenPayloadDto } from './dto/TokenPayloadDto';

describe('AuthController', () => {
  const defaultUser = new UserEntity();

  let app: TestingModule;

  beforeAll(async () => {
    app = await Test.createTestingModule({
      controllers: [AuthController],
      providers: [
        {
          provide: AuthService,
          useValue: {
            createAccessToken: () =>
              Promise.resolve(
                new TokenPayloadDto({ expiresIn: 3600, accessToken: 'token' }),
              ),
            validateUser: () => Promise.resolve(defaultUser),
          },
        },
        {
          provide: UserService,
          useValue: {
            createUser: () => Promise.resolve(defaultUser),
          },
        },
      ],
      imports: [],
    }).compile();
  });

  describe('root', () => {
    it('should be defined', () => {
      const appController = app.get<AuthController>(AuthController);
      expect(appController).toBeDefined();
    });
  });
});
spotlesscoder commented 1 year ago

see https://github.com/NarHakobyan/awesome-nest-boilerplate/pull/322