角度单元测试模拟服务仍然抛出无法读取未定义的属性'subscribe'



我再次陷入困境,尽管这个线程(MockService仍然会导致错误:无法读取未定义的属性';subscribe';(与此完全相同,但它仍然无法解决我的问题。

我确实有一个组件,它调用ngOnInit:上的一个简单函数

ngOnInit() {
this.getModules();
}
getModules() {
this.configService.getModulesToDisplay().subscribe(modules => {
this.modulesToDisplay = modules;
}
);
}

我想测试两件事:

ngOnInit上是否调用了getModules

this.modulesToDisplayed得到某个结果时是否重新分配

所以我嘲笑了我的服务,但第一次测试仍然失败,TypeError"无法读取未定义的属性"subscribe"。

我把我的mock服务转移到了所有不同的领域,因为我确实猜测在测试开始构建组件时mock不可用。但我还是没能成功。我的测试看起来像:

describe('NavigationComponent', () => {
let component: NavigationComponent;
let fixture: ComponentFixture<NavigationComponent>;
let configServiceMock: any;
beforeEach(async(() => {
configServiceMock = jasmine.createSpyObj('ConfigService', ['getModulesToDisplay']);
configServiceMock.getModulesToDisplay.and.returnValue( of(['module1', 'module2']) );
TestBed.configureTestingModule({
declarations: [
NavigationComponent
],
imports: [
RouterTestingModule,
HttpClientTestingModule
],
providers: [
{ provide: ConfigService, useValue: configServiceMock },
],
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
}).compileComponents();
beforeEach(() => {
// configServiceMock.getModulesToDisplay.and.returnValue( of(['module1', 'module2']) );
fixture = TestBed.createComponent(NavigationComponent);
component = fixture.componentInstance;
});
}));

我删除了fixture.dedetectChanges((以完全控制何时调用ngOnInit,因此我的测试看起来像:

it('should call getModulesToDisplay one time on ngOninit()', () => {
const spyGetModules = spyOn(component, 'getModules');
component.ngOnInit();
expect(spyGetModules).toHaveBeenCalledTimes(1);
});

第一个测试失败,出现无法读取订阅错误。但第二个通过时使用了正确的mock值。

it('should assign result to modulesToDisplay', () => {
component.getModules();
expect(component.modulesToDisplay.length).toBeGreaterThan(0);
});

任何关于我还缺少什么的暗示都将不胜感激!

与其在每个spec文件中写入jasminespy,不如创建一个可重用的Mock文件

export class MockConfigService{
getModulesToDisplay(){
return of({
// whatever module object structure is
})
}
}

并且在it块中:

it('should call getModulesToDisplay one time on ngOninit()', () => {
spyOn(component, 'getModules').and.callThrough();
component.ngOnInit();
expect(component.getModules).toHaveBeenCalledTimes(1);
});

最新更新