Jasmine 测试 属性 可观察订阅

Jasmine test property 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 吗?但它是组件的输入...

我已经检查过 and

谢谢!

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

对于这个测试用例,我只是简单地提供一个模拟 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!!!!");
  });
}