TestBed 模拟服务

TestBed mocking service

我得到了要用方法测试的组件:

     switchDocumentLanguage(lang, formData):any {
        if (lang === this.currentLang) {
          return null;
        }
        if (formData.invalid && this.currentLang === this.appConfig.defaultLanguage ||
          !this.documentFormData.content && this.currentLang === this.appConfig.defaultLanguage) {

          return this.modalService.open(this.setDefaultModal);

        }

        //(2*)
        if (formData.invalid || !this.documentFormData['content']) {
          return this.modalService.open(this.tabSwitchModal).result.then(() => {
            this.fillFormData(lang);
          }, (reason) => {
          });
        } else {
          return this.fillFormData(lang);
        }
      }

它属于标有 (2*)

的条件

在测试中我使用存根 class ModalService:

    class ModalService {
      open(someArg?: any){
        return {result : Promise.resolve('success')};
      }
    }

    const appConfig =
    {
      defaultLanguage: 'en-US'
    }

我的测试配置如下:

 describe('document.edit component test', () => {

  let component: DocumentEditComponent;
  let fixture: ComponentFixture<DocumentEditComponent>;

  beforeEach(() => {

    TestBed.configureTestingModule({
      imports: [FormsModule],

      schemas: [NO_ERRORS_SCHEMA],
      declarations: [DocumentEditComponent],
      providers: [{provide: AppConfig, useValue: appConfig},
        {provide: DocumentsService, useValue: documentsService},
        {provide: NgbModal, useClass: ModalService},
        {provide: ActivatedRoute, useValue: activatedRoute},
        {provide: BaThemeSpinner, useValue: loader},
        {provide: PopupResultService, useValue: popupResultService},
      ],
    })
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(DocumentEditComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

这是给我错误的测试:

  it("try to leave custom language with invalid form", async(() => {
      const componentService = fixture.debugElement.injector.get(NgbModal);

      let spyObj = spyOn(componentService, "open")

      component.documentFormData.content = "some test values";
      component.currentLang = "es-VE";


      fixture.detectChanges();
      component.switchDocumentLanguage("ru-Ru", {invalid: true})
      fixture.detectChanges();

      fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(spyObj).toHaveBeenCalled()
      })
    }));

错误文本:

document.edit component test try to leave custom language with invalid form
Failed: Cannot read property 'result' of undefined
TypeError: Cannot read property 'result' of undefined

看起来我的存根 class "ModalService" 没有 return 任何东西,我试图把它放在那里 console.log() 但它从未出现过。 有人遇到过类似的吗?

它没有被调用,因为你有一个间谍。

可能你可以做的是,用 callThrough()

扩展间谍
let spyObj = spyOn(componentService, "open").and.callThrough();

编辑:

您也可以使用 returnValue()

let spyObj = spyOn(componentService, "open").and.returnValue({result : Promise.resolve('success')}); 

在这种情况下,不会调用 open(),相反,您将 return 与模拟 Class 方法 return 得到的结果相同。如果你使用这个,你也不需要模拟 Class。