Angular4中Jasmine测试NgRx沙箱类时注入失败问题
解决Angular4测试NgRx沙箱类时的注入失败问题
看起来你的测试模块没有正确配置MonitoringSandbox的依赖注入,导致Angular的测试注入器找不到这个类的提供者,最终抛出StaticInjectorError并让沙箱对象返回undefined。下面一步步帮你解决这个问题:
1. 补全测试模块的依赖配置
你的TestBed.configureTestingModule只导入了UnitTestsModule,但如果这个模块没有导出或提供MonitoringSandbox,Angular就无法找到它。你需要显式在providers数组中添加沙箱类,同时mock它的两个依赖服务(测试沙箱不需要真实的服务实现,用模拟对象即可):
beforeEach(async(() => { TestBed.configureTestingModule({ imports: [UnitTestsModule], providers: [ // 提供沙箱类本身 MonitoringSandbox, // Mock DeviceService(这里可以留空,因为测试用例暂时没用到它的方法) { provide: DeviceService, useValue: jasmine.createSpyObj('DeviceService', ['']) }, // Mock AppStateManagerService,需要包含沙箱用到的getFromStore和saveToStore方法 { provide: AppStateManagerService, useValue: jasmine.createSpyObj('AppStateManagerService', ['getFromStore', 'saveToStore']) } ] }).compileComponents(); // Angular4中如果涉及组件模板,需要加上这个编译步骤 }));
2. 正确获取沙箱实例
你原来用inject在第二个beforeEach中赋值this.MonitoringSandbox,这种方式容易出现上下文问题。更可靠的做法是直接用TestBed.get()获取实例:
// 提前声明变量 let monitoringSandbox: MonitoringSandbox; let appStateManager: jasmine.SpyObj<AppStateManagerService>; beforeEach(() => { monitoringSandbox = TestBed.get(MonitoringSandbox); appStateManager = TestBed.get(AppStateManagerService); });
3. 修正测试用例中的方法名(注意点)
另外,你测试用例里调用的setSelectedRow和getSelectedRow,在你提供的MonitoringSandbox代码里并不存在——对应的实际方法是setSelectedDevice和getDeviceIdWithRowIndex。如果这是笔误,记得修正测试用例的方法调用,否则即使注入成功,测试也会失败。
完整修正后的测试代码示例
describe('MonitoringSandbox', () => { let monitoringSandbox: MonitoringSandbox; let appStateManager: jasmine.SpyObj<AppStateManagerService>; beforeEach(async(() => { TestBed.configureTestingModule({ imports: [UnitTestsModule], providers: [ MonitoringSandbox, { provide: DeviceService, useValue: jasmine.createSpyObj('DeviceService', ['']) }, { provide: AppStateManagerService, useValue: jasmine.createSpyObj('AppStateManagerService', ['getFromStore', 'saveToStore']) } ] }).compileComponents(); })); beforeEach(() => { monitoringSandbox = TestBed.get(MonitoringSandbox); appStateManager = TestBed.get(AppStateManagerService); }); it('should set selected device correctly', () => { const testDeviceId = '143'; monitoringSandbox.setSelectedDevice(testDeviceId); // 验证AppStateManager的saveToStore方法是否被正确调用 expect(appStateManager.saveToStore).toHaveBeenCalledWith(new SetSelectedDevice(testDeviceId)); }); it('should get device id list from store', () => { const mockKvRows: Array<RowIdDeviceIdKeyValue> = [{ rowId: '1', deviceId: 'dev1' }]; // 模拟getFromStore返回的Observable appStateManager.getFromStore.and.returnValue(of(mockKvRows)); monitoringSandbox.getDeviceIdWithRowIndex().subscribe(kvRows => { expect(kvRows).toEqual(mockKvRows); }); }); });
为什么原来的代码会失败?
本质原因是测试模块没有提供MonitoringSandbox及其依赖服务,Angular无法创建这个类的实例,所以注入时抛出StaticInjectorError,最终导致this.MonitoringSandbox为undefined。
内容的提问来源于stack exchange,提问作者pankaj
相关产品推荐
相关产品推荐

