茉莉花测试属性可观察订阅

时间:2019-01-31 12:57:40

标签: angular testing jasmine observable subscribe

我有此代码:

export class ProgramComponent implements OnInit {
   @Input() events: Observable<any>;
   eventsSubscription: any;
   ...
   ngOnInit() {
      this.eventsSubscription = this.events.subscribe((event) => {
          ... <- Some code that I want to test!!!!
          console.log("The test doesn't get past here!!!!");
      });
   }
}

describe('BLA BLA BLA', () => {
   let component: ProgramComponent;
   let fixture: ComponentFixture<ProgramComponent>;

   beforeEach(async(() => {
       TestBed.configureTestingModule({
          imports: [
              ...
          ],
          declarations: [ProgramComponent],
          providers: [
              ...
          ]
       }).compileComponents();
    }));

    beforeEach(() => {
       fixture = TestBed.createComponent(ProgramComponent);
       component = fixture.componentInstance;

       // HERE I WANT TO SPY ON THAT EVENTS OBSERVABLE AND RETURN SOME VALUE
       // I tried this without success
       spyOn(component, 'events').and.returnValue({type: 'somevalue'}))

       fixture.detectChanges();
    });

    it('should create', () => {
       expect(component).toBeTruthy();
    });
});

问题在于Fixture.detectChanges();不会触发可观察事件的订阅。我必须使用spyOnProperty吗?但这是组件的输入...

我已经检查了thisthis

谢谢!

1 个答案:

答案 0 :(得分:0)

是的,您必须使用spyOnProperty,因为它是您要监视的属性。但是,即使它不是属性,您的间谍也不会返回期望的类型以使其正常工作。间谍的返回值只是一个普通对象{ type: 'somevalue' },但是events属性期望的值为Observable<any>类型。当组件尝试在subscribe属性上调用events时,这很可能会导致错误,但是普通对象没有提供该方法。

对于这个测试用例,我只提供一个模拟Observable并测试它发出的值是否已成功在您的组件中接收(我假设您正在将您从Observable接收的任何内容分配给组件)。

这可能看起来像这样:

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

it('should test the component', () => {
  // provide an Observable with whatever value you need in your component    
  component.events = of({type: 'somevalue'});

  // nothing happened yet
  expect(component.eventsSubscription).toBeFalsy();
  expect(component.valueReceived).toBeUndefined();

  // this should trigger change detection and your ngOnInit
  fixture.detectChanges();

  // verify whatever you need
  expect(component.eventsSubscription).toBeTruthy();
  expect(component.valueReceived).toEqual({type: 'somevalue'});
});

在您的组件中:

@Input() events: Observable<any>;
eventsSubscription: any;
valueReceived: any;

ngOnInit() {
  this.eventsSubscription = this.events.subscribe((event) => {
    this.valueReceived = event;
    console.log("The test doesn't get past here!!!!");
  });
}