Angular单元测试MockService仍然抛出无法读取未定义的属性“订阅”

时间:2020-10-14 10:36:14

标签: javascript angular typescript unit-testing karma-jasmine

我再次陷入困境,尽管此线程(MockService still causes error: Cannot read property 'subscribe' of undefined)完全是同一回事,但仍然无法解决我的问题。

我确实有一个组件,可以在ngOnInit上调用一个简单函数:

ngOnInit() {
  this.getModules();
}

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

我想测试两件事:

getModules上有ngOnInit被呼叫

this.modulesToDisplayed收到结果后是否重新分配

所以我嘲笑了我的服务,但是第一个测试仍然失败,并显示TypeError'无法读取未定义的属性'subscribe'。

我将模拟服务移到了所有不同的区域,因为我确实猜想当测试开始构建组件时该模拟不可用。但是我仍然无法做到。我的测试如下:

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.detectChanges(),以完全控制何时应调用ngOnInit,因此我的测试如下:

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

第一次测试失败,并显示“无法读取订阅”错误。但是第二个通过了正确的模拟值。

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

任何关于我还缺少什么的提示都将受到赞赏!

1 个答案:

答案 0 :(得分:-1)

不要在每个spy文件中写入茉莉花spec,而是创建一个可重复使用的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);
    });