首页 文章

如何在单元测试中模拟ApplicationRef

提问于
浏览
2

我试图通过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 回答

  • 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);
      }))
    

相关问题