【问题标题】:How to mock ApplicationRef in unit test如何在单元测试中模拟 ApplicationRef
【发布时间】:2018-01-18 14:34:49
【问题描述】:

我尝试通过 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 始终为空:

【问题讨论】:

    标签: angular angular-test


    【解决方案1】:

    我通过创建一个新的 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);
      }))
    

    【讨论】:

    • 这似乎解决了我在对话测试中也遇到的问题,但我实际上不明白为什么......您能否添加解释为什么这会解决问题?
    猜你喜欢
    • 2017-06-14
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2019-12-13
    • 2012-07-14
    • 2019-09-21
    • 2013-12-13
    • 2018-10-06
    相关资源
    最近更新 更多