NestJS createTestingModule中useFactory与useValue的区别及适用场景
NestJS 测试模块中
useValue 与 useFactory 的差异及适用场景 useValue 和 useFactory 都是NestJS自定义提供者的标准配置项,不仅可用于普通业务模块,在 createTestingModule 测试模块中也常用来替换真实依赖实现Mock,二者核心差异为:useValue 直接注入固定值,useFactory 通过工厂函数返回值动态生成注入内容。
1. useValue 用法与适用场景
定义
直接将预先定义的常量、模拟对象、固定值绑定到对应的注入令牌上,Nest解析依赖时会直接返回该值,不会执行额外运算。
适用场景
- 注入的模拟内容完全固定,不需要依赖其他服务
- 简单常量配置、静态Mock函数/对象,无需动态生成的场景
示例
// 提前定义固定的Mock对象 const mockUserService = { findById: jest.fn().mockResolvedValue({ id: 1, name: 'Test User' }) } const testingModule = await Test.createTestingModule({ providers: [ UserController, // 直接将固定Mock绑定到UserService令牌 { provide: UserService, useValue: mockUserService } ] }).compile()
2. useFactory 用法与适用场景
定义
绑定一个工厂函数,Nest解析对应依赖时会执行该函数,将返回值作为注入内容。可通过 inject 数组指定工厂函数依赖的其他提供者,也支持异步返回。
适用场景
- 模拟内容需要动态生成,比如根据不同测试环境、测试参数返回不同的Mock结果
- 模拟依赖本身需要依赖测试模块内的其他提供者
- 需要异步初始化模拟值的场景,工厂函数支持返回Promise,Nest会等待异步逻辑执行完成后再完成依赖注入
示例
const testingModule = await Test.createTestingModule({ providers: [ UserController, ConfigService, // 工厂函数依赖的服务需要先在模块中声明 { provide: UserService, inject: [ConfigService], // 指定工厂函数要注入的依赖 useFactory: async (configService: ConfigService) => { // 支持异步逻辑 const testEnv = await configService.get('TEST_ENV') return { findById: jest.fn().mockResolvedValue( testEnv === 'dev' ? { id: 1, name: 'Dev Test User' } : { id: 2, name: 'Prod Test User' } ) } } } ] }).compile()
快速对比
- 执行时机:
useValue的值在模块声明时就已确定;useFactory的值在依赖第一次被解析时才执行工厂函数生成 - 依赖支持:
useValue无法依赖其他提供者;useFactory可通过inject数组注入其他模块内的提供者 - 复杂度:
useValue语法更简单,适合静态Mock场景;useFactory灵活性更高,适合动态、有依赖、异步的Mock场景
内容的提问来源于stack exchange,提问作者Leonardo Schmitt
相关产品推荐
相关产品推荐

