我如何在 angular 测试中监视构造函数调用?

How i can spy constructor functions calls in my angular test?

我有一项服务在 constructor() 中进行订阅并调用函数:

constructor(private router: Router) {
    this.router.events.subscribe((e) => {
      if (e instanceof RouterEvent) {
        this.closeModal();
      }
});
  

在我的测试中我试过:

describe('ModalService', () => {
   let service: ModalService;
   beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      providers: [
        {
          provide: Router,
          useClass: routeStub,
        },
      ],
    });
    router = TestBed.get(Router);
    service = TestBed.get(ModalService);

  fit('should close modal when is a instance of RouterEvent', async () => {
    spyOn(service, 'closeModal');
    await router.navigate(['/']);
    expect(service.closeModal).toHaveBeenCalled();
  });

})

我的路由器存根:

export const routeStub = (): Partial<Router> => {
  const events = of(new RouterEvent(1, 'test'));
  return {
    events,
    navigate: (commands: any[], extras?: NavigationExtras) => {
      return new Promise<boolean>((resolve, reject) => resolve(true));
    },
  };
};

当我将 console.log('test') 放入 closeModal() 时,我的消息 test 正在打印,但我的预期消失 return 消息错误:

Expected spy closeModal to have been called.

问题

构造方法是在创建组件时调用的,所以当你测试它的时候,它已经被执行了。这就是测试失败但控制台日志显示该方法被调用的原因

解决方案

您需要监视 class 组件 prototype 实例

fit('should close modal when is a instance of RouterEvent', async () => {
    
    const closeModalSpy = spyOn(AppComponent.prototype, 'closeModal').and.callThrough()
    TestBed.createComponent(AppComponent);
    expect(closeModalSpy).toHaveBeenCalled()

  });

我已经测试了上面的方法并且有效