如何在单元测试中模拟ApplicationRef

时间:2017-10-23 15:36:07

标签: angular angular-test

我尝试通过Jasmine和Angular 4测试这两种方法,但this.applicationRef总是返回一个空对象。如何解决这个?

这是我的代码:

@Injectable()
class Dialog {
  ....
  getRootViewContainerRef(): ViewContainerRef {
    const appInstance = this.applicationRef.components[0].instance;

    if (!appInstance.viewContainerRef) {
      const appName = this.applicationRef.componentTypes[0].name;
      throw new Error(`Missing 'viewContainerRef' declaration in ${appName} constructor`);
    }

    return appInstance.viewContainerRef;
  }
}

createOverlay(parentContainerRef: ViewContainerRef): ComponentRef<DialogContainerComponent> {
  const rootContainerRef = parentContainerRef;
  const rootInjector = rootContainerRef.injector;

  const bindings = ReflectiveInjector.resolve([]);
  const injector = ReflectiveInjector.fromResolvedProviders(bindings, rootInjector);

  const overlayFactory = this.cfr.resolveComponentFactory(DialogContainerComponent);
  return rootContainerRef.createComponent(overlayFactory, rootContainerRef.length, injector);
}

这是我的测试脚本:

describe('Dialog service', () => {
  //let fixture: ComponentFixture<DialogInformationComponent>;
  //let component: DialogInformationComponent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [...],
      providers: [
        {provide: APP_BASE_HREF, useValue: '/'},
        Dialog, DialogContext
      ]
    });
  }));

  it('Dialog should be showed.', inject([Dialog], (service: Dialog) => {
    let res: any;
    service.open(DialogInformationComponent, message).subscribe((result) => {
       res = result;
    });
   expected(true).toBeTruethy();
  }));
});

但是,ApplicationRef始终为空:

enter image description here

1 个答案:

答案 0 :(得分:3)

我通过创建一个新的MockComponent然后将其推送到当前的TedBed ApplicationRef来解决:

 @Component({
    selector: 'app-dialog',
    template: ''
  })
  class MockDialogComponent {
    constructor(public viewContainerRef: ViewContainerRef) {
    }
  }

  @NgModule({
    imports: [DialogModule],
    declarations: [MockDialogComponent]
  })
  class MockDialogModule {
  }

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [CommonModule, MockDialogModule]
    });
  }));

  beforeEach(() => {
    appRef = TestBed.get(ApplicationRef) as ApplicationRef;
    fixture = TestBed.createComponent(MockDialogComponent);
    appRef.components.push(fixture.componentRef);
    de = fixture.debugElement;
    fixture.detectChanges();
  });

  it('Dialog should be showed.', inject([Dialog], (service: Dialog) => {
     service.open(DialogInformationComponent, message).subscribe();
     fixture.detectChanges();
     expect(service.isShow).toBe(true);
  }))