Jasmine 等待 Observable 订阅

Jasmine Wait for Observable Subscription

我有以下 class:

@Injectable()
export class MyService {
  private subscriptions: { [key: string]: Subscription } = {};

  constructor(private otherService: OtherService) {
  }

  public launchTimer(order: any): void {
    this.subscriptions[order.id] = timer(500, 300000).subscribe(
      () => {
        this.otherService.notify();
      },
    );
  }
}

我想编写一个单元测试,断言当 launchTimer() 被调用时,notify 方法 OtherService 被调用。 棘手的是,对 timer observable 的订阅是直接在方法中完成的,这意味着我不能直接在单元测试中进行订阅来进行断言。
到目前为止我想出的是以下测试失败,因为断言是在订阅之前完成的:

class OtherServiceMock {
  public notify(): void {}
}

describe('MyService', () => {
  let otherService: OtherServiceMock;
  let myService: MyService;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        { provide: OtherService, useClass: OtherServiceMock },
      ],
    });
    otherService = TestBed.get(OtherService);
    myService = TestBed.get(MyService);
  });

  it('launchTimer should call notify', () => {
    spyOn(otherService, 'notify');
    myService.launchTimer();
    expect(otherService.notify).toHaveBeenCalled();
  });
});

我尝试用 async 包装函数,我还使用 fakeAsynctick但似乎没有任何效果。 我有什么想法可以在做出断言之前等待订阅吗?

使用间隔和计时器测试可观察对象可能很棘手,但试试这个,如果这不起作用,我也可以用不同的方式来做。

class OtherServiceMock {
  public notify(): void {}
}

describe('MyService', () => {
  let otherService: OtherServiceMock;
  let myService: MyService;
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        { provide: OtherService, useClass: OtherServiceMock },
      ],
    });
    otherService = TestBed.get(OtherService);
    myService = TestBed.get(MyService);
  });

  it('launchTimer should call notify', fakeAsync(() => {
    // you're going to have to make `subscriptions` public for this to work !!
    spyOn(otherService, 'notify'); // don't need to callThrough to see if it was called or not
    myService.launchTimer({id: 1});
    tick(501);
    expect(otherService.notify).toHaveBeenCalled();
    myService.subscriptions['1'].unsubscribe(); // kill the timer subscription
  }));
});

=====================编辑======================= ============

您要么必须制作 subscriptions public,要么提供一种 public 方法来取消订阅该对象中的订阅。