我正在尝试模拟一个存储库。我不想进行实际的数据库调用。我(认为我)正在关注 NestJS 的文档以及某些 stackoverflow 项目。
但是,当我运行测试时,出现以下错误:
JwtStrategy › validate › throws an unauthorized exception as user cannot be found
Nest can't resolve dependencies of the UserEntityRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context.
Potential solutions:
- If DataSource is a provider, is it part of the current TypeOrmModule?
- If DataSource is exported from a separate @Module, is that module imported within TypeOrmModule?
@Module({
imports: [ /* the Module containing DataSource */ ]
})
现在据我了解,似乎 UserEntityRepository 没有被正确模拟。因为它是用户服务类中的第一个(索引 [0])依赖项:
./user.service.ts
@Injectable()
export class UserService {
constructor(
@InjectRepository(UserEntity)
private userRepository: Repository<UserEntity>
) {}
async findOneBy({ username }): Promise<UserEntity> {
return await this.userRepository.findOneBy({ username })
}
}
./jwt.strategy.ts
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
private userService: UserService,
) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.JWT_SECRET || config.get('jwt.secret'),
})
}
async validate(payload: JwtPayload) {
const { username } = payload;
const user = await this.userService.findOneBy({username});
if (!user) {
throw new UnauthorizedException();
}
return user;
}
}
./jwt.strategy.spect.ts
const mockUserRepositoryFactory = jest.fn(() => ({
findOneBy: jest.fn(entity => entity),
}));
describe('JwtStrategy', () => {
let jwtStrategy: JwtStrategy;
let userService;
beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [UserModule],
providers: [
JwtStrategy,
UserService,
// shouldn't this correctly provide the datasource?
{
provide: getRepositoryToken(UserEntity),
useFactory: mockUserRepositoryFactory,
},
]
}).compile();
jwtStrategy = await module.get<JwtStrategy>(JwtStrategy);
userService = await module.get<UserService>(UserService);
});
describe('validate', () => {
it('validates and returns user based on JWT payload', async () => {
const user = new UserEntity();
user.username = 'TestUser';
userService.findOneBy.mockResolvedValue(user);
const result = await jwtStrategy.validate({ username: 'TestUser' });
expect(userService.findOneBy).toHaveBeenCalledWith({ username: 'TestUser' });
expect(result).toEqual(user);
});
it('throws an unauthorized exception as user cannot be found', async () => {
userService.findOneBy.mockResolvedValue(null);
expect(jwtStrategy.validate({ username: 'TestUser' })).rejects.toThrow(UnauthorizedException);
});
});
});
=====更新
在 Codesandbox 中创建了最小设置。
https://codesandbox.io/s/xenodochial-benz-kve4eq?file=/test/jwt.test.js
但不知何故,测试选项卡没有显示在沙箱中。