首页 > 解决方案 > 在函数中使用 subscribe 测试 Observable

问题描述

这是测试台设置。模拟并提供所需的一切:

 let component: PageUploadContainer;
  let store;
  let route;
  let fixture: ComponentFixture<PageUploadContainer>;
  const sanitizer = jasmine.createSpyObj('sanitizer', ['bypassSecurityTrustResourceUrl']);
  sanitizer.bypassSecurityTrustResourceUrl.and.callFake(url => url);
  const mockTranslate = {
    instant: label => label,
  };

  beforeEach(() => {
    store = createMockStore<AppState>(reducers);
    route = new MockActivatedRoute();
  });

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [translationModule],
      declarations: [
        PageUploadContainer,
        MockTranslatePipe,
        MockTranslateCutPipe,
      ],
      schemas: [NO_ERRORS_SCHEMA],
      providers: [
        FormBuilder,
        { provide: DomSanitizer, useValue: sanitizer },
        { provide: Store, useValue: store },
        { provide: ActivatedRoute, useValue: route },
        { provide: TranslateService, useFactory: () => mockTranslate },
      ],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(PageUploadContainer);
    component = fixture.componentInstance;
    component.mappingTriggered$ = Observable.of(false);
  });

我有以下代码,我用 testBed 设置了我的测试:

onGoTo(uploadStep: string) {
    if (uploadStep === NAVIGATION.DEFAULT) {
      this.store.dispatch(new ReplaceSelectedCompanies([]));
      this.companyIds$.filter(isEmpty)
        .take(1)
        .subscribe(() => {
          this.store.dispatch(new Navigate({ direction: uploadStep}));
        });
    } else {
      this.store.dispatch(new Navigate({ direction: uploadStep}));
    }
  }

还有我的测试。该测试失败,因为new Navigate({ direction: uploadStep})它是异步的,所以没有被调用

it('if navigation default and companyIds empty should call navigate', () => {
       component.companyIds$ = Observable.of(['123', '234']);
      component.onGoTo(NAVIGATION.DEFAULT);
      expect(store.dispatch).toHaveBeenCalledWith(new ReplaceSelectedCompanies([]));
      expect(store.dispatch).toHaveBeenCalledWith(new Navigate({ direction: NAVIGATION.DEFAULT }));
    });

你能帮我如何测试这些方法吗?

标签: angularjasminerxjsangular5rxjs6

解决方案


虽然我不确定,但您可能只需要导入asyncangular 提供的方法。

一般示例

it("description", async( /* function */ ));

你的代码

import { async } from "@angular/core/testing";

it('if navigation default and companyIds empty should call navigate', async(() => {
  component.companyIds$ = Observable.of(['123', '234']);
  component.onGoTo(NAVIGATION.DEFAULT);
  expect(store.dispatch)
    .toHaveBeenCalledWith(new ReplaceSelectedCompanies([]));
  expect(store.dispatch)
    .toHaveBeenCalledWith(new Navigate({ direction: NAVIGATION.DEFAULT }));
}));

建议

首先,我会观看有关 Angular 6 异步单元测试的视频。整个单元测试系列也很好。

你有很多自定义的模拟类,所以我不能对此发表太多评论。我建议使用RouterTestingModule.withRoutes({ /* test routes */ }). 这是该系列中另一个关于 RouterTestingModule 的视频

然后,您总是可以得到模拟的路由器router = TestBed.get(Router)或其他由RouterTestingModule.


推荐阅读