Angular测试mock setLocalStorage_SingleValue遇Function expected错误排查
Angular测试中mock localStorage方法时出现"Function expected"错误的解决办法
我来帮你分析下这个问题,虽然你的测试最终拿到了预期值,但控制台抛出的"Function expected"错误其实是在提示你mock的逻辑里存在隐性问题。
错误原因分析
结合你的代码和报错栈信息,最可能的触发原因有两个:
_mockConfiguration的setLocalStorage_SingleValue未正确定义为函数:当callFake回调里尝试调用这个方法时,如果它不是一个可执行的函数,就会直接抛出"Function expected"错误。- Spy目标实例与组件注入实例不一致:如果你测试里spy的
_configuration和组件实际依赖的_configuration不是同一个对象,就会导致spy逻辑失效,同时触发真实方法的执行——而真实的setLocalStorage_SingleValue可能因为测试环境的限制(比如无法访问真实localStorage)抛出错误。
另外,你用普通function作为callFake回调时,还可能存在this指向混乱的问题,不过从报错信息来看这个可能性稍低,但也是需要注意的细节。
修复方案
我们可以用Jasmine自带的spy工具简化mock逻辑,同时确保组件注入的是我们预设的mock实例:
步骤1:创建并提供Mock服务
在beforeEach中定义完整的mock服务,通过TestBed的providers确保组件使用这个mock:
let fixture: ComponentFixture<YourComponent>; let component: YourComponent; let mockConfiguration: jasmine.SpyObj<ConfigurationService>; beforeEach(async () => { // 创建带spy方法的mock服务 mockConfiguration = jasmine.createSpyObj('ConfigurationService', [ 'setLocalStorage_SingleValue', 'getLocalStorage_SingleValue' ]); // 模拟localStorage的存储逻辑 const mockStorage: Record<string, string> = {}; mockConfiguration.setLocalStorage_SingleValue.and.callFake((key: string, value: string) => { mockStorage[key] = value; }); mockConfiguration.getLocalStorage_SingleValue.and.callFake((key: string) => { return mockStorage[key]; }); await TestBed.configureTestingModule({ declarations: [YourComponent], providers: [ { provide: ConfigurationService, useValue: mockConfiguration } ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(YourComponent); component = fixture.componentInstance; });
步骤2:简化测试逻辑
现在测试方法不需要手动spy,直接调用ngOnInit并断言即可:
it('should set and get values via Configuration service', fakeAsync(() => { // 触发组件的初始化逻辑 component.ngOnInit(); fixture.detectChanges(); // 断言set方法被正确调用 expect(mockConfiguration.setLocalStorage_SingleValue).toHaveBeenCalledWith( 'previousUrl', window.location.href ); // 断言pageinationcount拿到了预期值 expect(component.pageinationcount).toEqual(window.location.href); }));
为什么原来的写法会报错?
你之前的代码里,要么是_mockConfiguration的setLocalStorage_SingleValue未被定义为有效函数,要么是spy的实例和组件使用的实例不匹配。通过上面的方式,我们直接用Jasmine的createSpyObj创建规范的mock服务,同时通过TestBed确保组件注入的是这个mock,从根源上避免了实例不一致和方法未定义的问题。
内容的提问来源于stack exchange,提问作者Ramesh Rajendran
相关产品推荐
相关产品推荐

