[英]Nest can't resolve dependencies of the AuthService (AuthRepository, ?)
I'm trying to implement JWT into my project.我正在尝试将 JWT 实施到我的项目中。 I've followed the steps as outline in https://www.npmjs.com/package/@nestjs/jwt#usage
我已按照https://www.npmjs.com/package/@nestjs/jwt#usage 中的概述步骤操作
auth.module.ts auth.module.ts
import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { JwtModule } from '@nestjs/jwt';
import { AuthRepository } from './auth.repository';
@Module({
imports: [
JwtModule.register({ secret: process.env.JWT_SECRET || 'ABCDE12345' }),
TypeOrmModule.forFeature([AuthRepository]),
],
exports: [TypeOrmModule, AuthService],
providers: [AuthService],
controllers: [AuthController],
})
export class AuthModule {}
auth.service.ts auth.service.ts
import { Injectable, NotFoundException, UnauthorizedException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { AuthEntity } from './auth.entity';
import { LoginDTO } from './dto/login.dto';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';
import crypto from 'crypto';
import { AuthRepository } from './auth.repository';
// export interface FindWhereData {
// readonly email: string;
// readonly password: string;
// }
export interface LoginResponse {
readonly token: string;
readonly refresh_token: string;
}
@Injectable()
export class AuthService {
constructor(
@InjectRepository(AuthRepository)
private authRepository: AuthRepository,
private jwtService: JwtService
) {}
/**
* Login user service
*
* @param doc
*/
public async login(doc: LoginDTO): Promise<LoginResponse> {
// verify user email
const user = await this.authRepository.findOne({ email: doc.email });
if (!user) {
throw new NotFoundException('Could not find user');
}
// verify password
const passwordsMatch = await this.passwordsAreEqual(doc.password, user.password);
if (!passwordsMatch) {
throw new UnauthorizedException('Incorrect login credentials');
}
// generate JWT
const token = await this.jwtService.signAsync({ id: user.id });
// create the refresh token
const refreshToken = crypto.randomBytes(256).toString('hex');
// store the refresh token
return {
token: token,
refresh_token: refreshToken,
};
}
/**
* Generate a hashed password
*
* @param password
*/
public async hashPassword(password: string): Promise<string> {
const salt = await bcrypt.genSalt();
return await bcrypt.hash(password, salt);
}
/**
* Compare password against an encrypted string
*
* @param password
* @param encryptedPassword
*/
public async passwordsAreEqual(password: string, encryptedPassword: string): Promise<boolean> {
return await bcrypt.compare(password, encryptedPassword);
}
/**
* Find a record by column attribute and value
*
* @param queryObject
*
*/
public async findWhere(queryObject): Promise<AuthEntity> {
const authEntity = await this.authRepository.findOne({ where: queryObject });
if (!authEntity) {
return null;
}
return authEntity;
}
public async findOne(id: string): Promise<AuthEntity> {
return this.authRepository.findOne(id);
}
}
auth.repository.ts auth.repository.ts
import { EntityRepository, Repository } from "typeorm";
import { AuthEntity } from "./auth.entity";
@EntityRepository(AuthEntity)
export class AuthRepository extends Repository<AuthEntity> {}
app.module.ts app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { RouterModule } from 'nest-router';
import { routes } from './routes';
import { ConfigModule } from '@nestjs/config';
import configuration from './config/configuration';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Connection } from 'typeorm';
import { AuthModule } from './auth/auth.module';
@Module({
imports: [
RouterModule.forRoutes(routes),
ConfigModule.forRoot({
load: [configuration],
}),
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.POSTGRES_HOST || 'localhost',
port: 5432,
username: process.env.POSTGRES_USERNAME || 'postgres',
password: process.env.POSTGRES_PASSWORD || 'password',
database: process.env.POSTGRES_DATABASE || 'service-auth',
autoLoadEntities: true,
synchronize: true,
}),
AuthModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {
constructor(private readonly connection: Connection) {
console.log('connection status: ' + connection.isConnected);
}
}
auth.service.spec.ts auth.service.spec.ts
import { JwtModule, JwtService } from '@nestjs/jwt';
import { Test, TestingModule } from '@nestjs/testing';
import { AuthEntity } from './auth.entity';
import { AuthRepository } from './auth.repository';
import { AuthService } from './auth.service';
describe('AuthService', () => {
let authService: AuthService;
let authRepository: AuthRepository;
const mockAuthRepository = () => ({
login: jest.fn(),
});
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
AuthService,
// JwtModule,
{
provide: getRepositoryToken(AuthRepository),
useFactory: mockAuthRepository,
},
{
provide: JwtService,
useValue: {
signAsync: jest.fn(() => 'token'),
}
}
]
}).compile();
authService = await module.get<AuthService>(AuthService);
authRepository = await module.get<AuthRepository>(AuthRepository);
});
/**
* Test that the service is defined
*/
it('should be defined', () => {
expect(authService).toBeDefined();
});
});
When I run npm run test
I get the following error message:当我运行
npm run test
我收到以下错误消息:
FAIL src/auth/auth.service.spec.ts
● AuthService › should be defined
Nest can't resolve dependencies of the AuthService (AuthRepository, ?). Please make sure that the argument JwtService at index [1] is available in the RootTestModule context.
Potential solutions:
- If JwtService is a provider, is it part of the current RootTestModule?
- If JwtService is exported from a separate @Module, is that module imported within RootTestModule?
@Module({
imports: [ /* the Module containing JwtService */ ]
})
I know the error is probably pretty clear to seasoned Node/Nest developer but I cannot figure out what the RootTestModule is and how to get JwtModule imported.我知道这个错误对于经验丰富的 Node/Nest 开发人员来说可能很清楚,但我无法弄清楚 RootTestModule 是什么以及如何导入 JwtModule。
I believe I have followed the setup correctly but adding this JwtModule to the AuthService is causing the service to be undefined in my unit tests.我相信我已经正确地遵循了设置,但是将此 JwtModule 添加到 AuthService 会导致我的单元测试中未定义该服务。
Repo https://github.com/marcuschristiansen/nestjs-auth回购https://github.com/marcuschristiansen/nestjs-auth
You should be adding a custom provider for the JwtService
so that you can mock it.您应该为
JwtService
添加一个自定义提供程序,以便您可以模拟它。 A custom provider could look like自定义提供程序可能看起来像
{
provide: JwtService,
useValue: {
signAsync: jest.fn(() => 'token'),
}
}
To tell Nest to inject an object that has a signAsync()
method that when called returns the string 'token'
so that it will always be the same in your tests.告诉 Nest 注入一个具有
signAsync()
方法的对象,该方法在调用时返回字符串'token'
以便它在您的测试中始终相同。
This object goes in the providers
array, just like the AuthRepository
mock这个对象进入
providers
数组,就像AuthRepository
模拟
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.