NestJS/TypeORM 单元测试:无法解析 JwtService 的依赖关系

nob*_*are 6 jestjs typeorm nestjs nestjs-jwt

我正在尝试对该控制器进行单元测试并模拟它所需的服务/存储库。

\n
@Controller('auth')\nexport class AuthController {\n    constructor(\n        private readonly authService: AuthService,\n        private readonly usersService: UsersService,\n    ) {}\n\n    @Post('register')\n    public async registerAsync(@Body() createUserModel: CreateUserModel) {\n        const result = await this.authenticationService.registerUserAsync(createUserModel);\n\n        // more code here\n    }\n\n    @Post('login')\n    public async loginAsync(@Body() login: LoginModel): Promise<{ accessToken: string }> {\n        const user = await this.usersService.getUserByUsernameAsync(login.username);\n\n        // more code here\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的单元测试文件:

\n
describe('AuthController', () => {\n    let authController: AuthController;\n    let authService: AuthService;\n\n    beforeEach(async () => {\n        const moduleRef: TestingModule = await Test.createTestingModule({\n            imports: [JwtModule],\n            controllers: [AuthController],\n            providers: [\n                AuthService,\n                UsersService,\n                {\n                    provide: getRepositoryToken(User),\n                    useClass: Repository,\n                },\n            ],\n        }).compile();\n\n        authController = moduleRef.get<AuthenticationController>(AuthenticationController);\n        authService = moduleRef.get<AuthenticationService>(AuthenticationService);\n    });\n\n    describe('registerAsync', () => {\n        it('Returns registration status when user registration succeeds', async () => {\n            let createUserModel: CreateUserModel = {...}\n\n            let registrationStatus: RegistrationStatus = {\n                success: true,\n                message: 'User registered successfully',\n            };\n\n            jest.spyOn(authService, 'registerUserAsync').mockImplementation(() =>\n                Promise.resolve(registrationStatus),\n            );\n\n            expect(await authController.registerAsync(createUserModel)).toEqual(registrationStatus);\n        });\n    });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

但是当运行这个时,我收到以下错误:

\n
  \xe2\x97\x8f AuthController \xe2\x80\xba registerAsync \xe2\x80\xba Returns registration status when user registration succeeds\n\n    Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument JWT_MODULE_OPTIONS at index [0] is available in the JwtModule context.\n\n    Potential solutions:\n    - If JWT_MODULE_OPTIONS is a provider, is it part of the current JwtModule?\n    - If JWT_MODULE_OPTIONS is exported from a separate @Module, is that module imported within JwtModule?\n      @Module({\n        imports: [ /* the Module containing JWT_MODULE_OPTIONS */ ]\n      })\n\n      at Injector.lookupComponentInParentModules (../node_modules/@nestjs/core/injector/injector.js:191:19)\n      at Injector.resolveComponentInstance (../node_modules/@nestjs/core/injector/injector.js:147:33)\n      at resolveParam (../node_modules/@nestjs/core/injector/injector.js:101:38)\n          at async Promise.all (index 0)\n      at Injector.resolveConstructorParams (../node_modules/@nestjs/core/injector/injector.js:116:27)\n      at Injector.loadInstance (../node_modules/@nestjs/core/injector/injector.js:80:9)\n      at Injector.loadProvider (../node_modules/@nestjs/core/injector/injector.js:37:9)\n      at Injector.lookupComponentInImports (../node_modules/@nestjs/core/injector/injector.js:223:17)\n      at Injector.lookupComponentInParentModules (../node_modules/@nestjs/core/injector/injector.js:189:33)\n\n  \xe2\x97\x8f AuthController \xe2\x80\xba registerAsync \xe2\x80\xba Returns registration status when user registration succeeds\n\n    Cannot spyOn on a primitive value; undefined given\n\n      48 |             };\n      49 |\n    > 50 |             jest.spyOn(authService, 'registerUserAsync').mockImplementation(() =>\n         |                  ^\n      51 |                 Promise.resolve(registrationStatus),\n      52 |             );\n      53 |\n\n      at ModuleMockerClass.spyOn (../node_modules/jest-mock/build/index.js:780:13)\n      at Object.<anonymous> (Authentication/authentication.controller.spec.ts:50:18)\n
Run Code Online (Sandbox Code Playgroud)\n

我不太确定如何继续,所以我需要一些帮助。

\n

Jay*_*iel 5

我在这里注意到一些事情:

  1. 如果您正在测试控制器,则不需要模拟超过一层的深度 pf 服务

  2. imports您几乎不应该在单元测试中遇到需要数组的用例。

您可以为测试用例执行类似于以下内容的操作:

beforeEach(async () => {
  const modRef = await Test.createTestingModule({
    controllers: [AuthController],
    providers: [
      {
        provide: AuthService,
        useValue: {
          registerUserAsync: jest.fn(),
        }

      },
      {
        provide: UserService,
        useValue: {
          getUserByUsernameAsync: jest.fn(),
        }
      }
    ]
  }).compile();
});
Run Code Online (Sandbox Code Playgroud)

现在您可以使用 auth 服务和用户服务modRef.get()并将它们保存到变量中以便稍后向它们添加模拟。您可以查看这个测试存储库,其中有很多其他示例。