问题描述
在此问题中,对此进行了长时间的讨论.
There's a longish discussion about how to do this in this issue.
我已经尝试了许多建议的解决方案,但是运气不高.
I've experimented with a number of the proposed solutions but I'm not having much luck.
任何人都可以提供一个具体示例,说明如何使用注入的存储库和模拟数据来测试服务吗?
Could anyone provide a concrete example of how to test a service with an injected repository and mock data?
推荐答案
假设我们有一个非常简单的服务,该服务通过id查找用户实体:
Let's assume we have a very simple service that finds a user entity by id:
export class UserService {
constructor(@InjectRepository(UserEntity) private userRepository: Repository<UserEntity>) {
}
async findUser(userId: string): Promise<UserEntity> {
return this.userRepository.findOne(userId);
}
}
然后,您可以使用以下模拟工厂模拟UserRepository
(根据需要添加更多方法):
Then you can mock the UserRepository
with the following mock factory (add more methods as needed):
// @ts-ignore
export const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({
findOne: jest.fn(entity => entity),
// ...
}));
使用工厂可确保每次测试都使用新的模拟.
Using a factory ensures that a new mock is used for every test.
describe('UserService', () => {
let service: UserService;
let repositoryMock: MockType<Repository<UserEntity>>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserService,
// Provide your mock instead of the actual repository
{ provide: getRepositoryToken(UserEntity), useFactory: repositoryMockFactory },
],
}).compile();
service = module.get<UserService>(UserService);
repositoryMock = module.get(getRepositoryToken(UserEntity));
});
it('should find a user', async () => {
const user = {name: 'Alni', id: '123'};
// Now you can control the return value of your mock's methods
repositoryMock.findOne.mockReturnValue(user);
expect(service.findUser(user.id)).toEqual(user);
// And make assertions on how often and with what params your mock's methods are called
expect(repositoryMock.findOne).toHaveBeenCalledWith(user.id);
});
});
出于类型安全性和舒适性的考虑,您可以对模拟使用以下类型(远非完美,当在接下来的主要版本中开玩笑本身开始使用Typescript时,可能会有更好的解决方案):
For type safety and comfort you can use the following typing for your mocks (far from perfect, there might be a better solution when jest itself starts using typescript in the upcoming major releases):
export type MockType<T> = {
[P in keyof T]: jest.Mock<{}>;
};
这篇关于将TypeORM存储库注入NestJS服务以进行模拟数据测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!