如何对使用Angular 14新inject函数的函数进行单元测试?
测试Angular inject函数封装的函数的实用方法
不用创建测试专用组件/服务,有两种高效的方式解决这个问题:
方法一:使用TestBed.runInInjectionContext
Angular的测试工具提供了runInInjectionContext方法,能直接在TestBed配置的依赖上下文里执行目标函数,完美适配inject的调用要求。
示例代码
假设你要测试的函数是:
export function useMyService() { const myService = inject(MyService); return myService.doSomething(); }
测试用例可以这么写:
describe('useMyService', () => { let mockMyService: jasmine.SpyObj<MyService>; beforeEach(() => { // 创建模拟服务 mockMyService = jasmine.createSpyObj('MyService', ['doSomething']); // 配置TestBed,注入模拟依赖 TestBed.configureTestingModule({ providers: [ { provide: MyService, useValue: mockMyService } ] }); }); it('应该调用MyService的doSomething方法', () => { mockMyService.doSomething.and.returnValue('测试结果'); // 在注入上下文里执行目标函数 const result = TestBed.runInInjectionContext(() => useMyService()); expect(mockMyService.doSomething).toHaveBeenCalled(); expect(result).toBe('测试结果'); }); });
方法二:手动创建Injector并使用runInContext
如果不想依赖TestBed的全局配置,可以直接用Injector.create手动构建注入器,在它的上下文里执行函数,更轻量灵活。
示例代码
describe('useMyService', () => { let mockMyService: jasmine.SpyObj<MyService>; beforeEach(() => { mockMyService = jasmine.createSpyObj('MyService', ['doSomething']); }); it('应该调用MyService的doSomething方法', () => { mockMyService.doSomething.and.returnValue('测试结果'); // 手动创建注入器,传入模拟依赖 const injector = Injector.create({ providers: [{ provide: MyService, useValue: mockMyService }] }); // 在注入器上下文执行函数 const result = injector.runInContext(() => useMyService()); expect(mockMyService.doSomething).toHaveBeenCalled(); expect(result).toBe('测试结果'); }); });
这两种方法都能避免创建冗余的测试组件/服务,直接为目标函数提供合法的依赖注入上下文,满足单元测试的需求。
内容的提问来源于stack exchange,提问作者Shachar Har-Shuv
相关产品推荐
相关产品推荐

