我对 Nestjs 登录端点进行了测试。但我有错误。 您能帮忙吗?
我的测试文件:
import { Test, TestingModule } from "@nestjs/testing";
import { UsersController } from "./users.controller";
import { UsersService } from "./users.service";
import { INestApplication } from '@nestjs/common';
import { UsersModule } from "./users.module";
import * as request from 'supertest';
import { CreateUserDto } from "./dto/createUser.dto";
describe('first test', () => {
let usersController: UsersController;
let usersService: UsersService;
let app: INestApplication;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
imports: [UsersModule],
})
.overrideProvider(UsersService)
.useValue(usersService)
.compile();
app = moduleRef.createNestApplication();
await app.init();
});
it('/POST create', async () => {
const createUserDto = new CreateUserDto();
createUserDto.username = "deneme";
createUserDto.password = "102030";
// Act
const response = await request(app.getHttpServer())
.post(`/users/create`)
.send(createUserDto);
expect(response.status).toEqual(200);
});
});
我的用户.service.ts:
import { HttpException, Injectable } from "@nestjs/common";
import { InjectModel } from "@nestjs/mongoose";
import { Model, Types } from "mongoose";
import { CreateUserDto } from "./dto/createUser.dto";
import { FollowUserDto } from "./dto/followUser.dto";
import { LoginUserDto } from "./dto/loginUser.dto";
import * as bcrypt from 'bcrypt';
import { JwtService } from "@nestjs/jwt";
import { Users } from "src/schemas/user.schema";
@Injectable()
export class UsersService {
constructor(
@InjectModel(Users.name) private userModel: Model<Users>,
private jwtService: JwtService
) {}
async loginUser(loginUserDto: LoginUserDto) {
const {username, password} = loginUserDto
const user = await this.userModel.findOne({username});
if (!user) {
throw new HttpException("User Not Found", 400);
}
const passMatch = await bcrypt.compare(password, user.password);
if (!passMatch) {
throw new HttpException("User Pass Does not match", 400);
}
return this.generateUserToken(user);
}
async generateUserToken(user) {
const accessToken = this.jwtService.sign({user}, {expiresIn: '1h'});
return accessToken;
}
async createUser(createUserDto: CreateUserDto) {
const {username, password} = createUserDto;
const usernameInUse = await this.userModel.findOne({username});
if (usernameInUse) {
throw new HttpException("Username In Use", 400);
}
const hashedPass = await bcrypt.hash(password, 10);
await this.userModel.create({
username,
password: hashedPass
});
return true;
}
async followUser(followUserDto: FollowUserDto, userId: string) {
const myInfo = await this.userModel.findById(userId);
if (!myInfo) {
throw new HttpException("My Info Not Found", 400);
}
const followUserInfo = await this.userModel.findById(followUserDto.followId);
if (!followUserInfo) {
throw new HttpException("Followed User Info Not Found", 400);
}
const myInfoResult = await this.userModel.updateOne({_id: myInfo._id}, {
$push: {
follows: followUserInfo,
},
});
return myInfoResult;
}
}
错误是:
Nest 无法解析 UsersService(UsersModel,?)的依赖关系。请确保索引 [1] 处的参数 JwtService 在 UsersModule 上下文中可用。
就像 Micael Levi 在评论中所说,拥有 UsersModule 的定义将帮助我们看到问题。
但我认为问题出在这部分
.overrideProvider(UsersService)
.useValue(usersService)
您可以使用自定义值覆盖
UsersService
中 UsersModule
的默认值。
问题是您给出的值(变量usersService
)是undefined
。所以模块将无法使用它。
如果您想继续使用此变量,您将需要使用正确的依赖项自行实例化
UsersService
。像这样的东西:
let usersService = new UsersService(*The user model (from mongoose?)*, new JwtService());
它应该可以工作,只要你设法正确地获取用户模型(我不知道 Mongoose 是如何工作的,所以在这里无法提供帮助)
但是
根据您当前的测试,我并没有真正看到覆盖 UserService 的要点。通常,当我们需要改变某些东西的行为时,我们会重写服务。
例如,假设您在没有数据库的情况下运行测试,因为您只想测试 JS 部分。您可以用另一个服务覆盖该服务,以防止该服务发送数据库请求。
但就您而言,您似乎(目前)只是测试正常行为。因此,如果是这种情况,您不应该覆盖任何内容,只需正常构建模块即可。
const moduleRef = await Test.createTestingModule({
imports: [UsersModule],
}).compile();
如果您只想在测试中直接使用
UsersService
而不发送HTTP请求,您可以直接从应用程序获取实例,而无需手动实例化它,如下所示:
const usersService = app.get(UsersService)