关于如何做到这一点,在这issue篇文章中有一个长期的讨论.

我已经try 了许多提议的解决方案,但运气不太好.

有人能提供一个具体的例子,说明如何使用注入的存储库和模拟数据测试服务吗?

推荐答案

假设我们有一个非常简单的服务,它通过id查找用户实体:

export class UserService {
  constructor(@InjectRepository(UserEntity) private userRepository: Repository<UserEntity>) {
  }

  async findUser(userId: string): Promise<UserEntity> {
    return this.userRepository.findOne(userId);
  }
}

然后,您可以使用以下模拟工厂模拟UserRepository(根据需要添加更多方法):

// @ts-ignore
export const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({
  findOne: jest.fn(entity => entity),
  // ...
}));

使用工厂可以确保每次测试都使用新的模拟.

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);
  });
});

为了确保键入的安全性和舒适性,您可以在(部分)模拟中使用以下键入(远不是完美的,当jest本身在即将发布的主要版本中开始使用typescript时,可能会有更好的解决方案):

export type MockType<T> = {
  [P in keyof T]?: jest.Mock<{}>;
};

Typescript相关问答推荐

PrimeNG Inputnumber,具有自定义号码格式器

具有匹配键的通用对象界面

APP_INITIALIZER—TypeError:appInits不是函数

Angular中的其他服务仅获取默认值

无法将select选项的值设置为ngFor循环中的第一个元素

返回同时具有固定键和变量键的对象的函数的返回类型

类型脚本中没有接口的中间静态类

是否存在类型联合的替代方案,其中包括仅在某些替代方案中存在的可选属性?

为什么我的一个合成函数不能推断类型?

React Typescript项目问题有Redux-Toolkit userSlice角色问题

类型脚本满足将布尔类型转换为文字.这正常吗?

TypeScrip泛型类未提供预期的类型错误

使用TypeScrip5强制使用方法参数类型的实验方法修饰符

如何避免从引用<;字符串&>到引用<;字符串|未定义&>;的不安全赋值?

TypeScrip:使用Cypress测试包含插槽的Vue3组件

是否可以定义引用另一行中的类型参数的类型?

任何导航器都未处理有效负载为";params";:{";roomId";:";...";}}的导航操作

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

可以用任意类型实例化,该类型可能与

具有枚举泛型类型的 Typescript 对象数组