笑话测试计划程序方法

问题描述

我有一个运行调度程序的简单类。

类似这样的东西:

export class ExportScheduler {
    constructor(cron: string,private product: Product) {
        cron.schedule(cron,() => this.export());
    }

    async export(): Promise<any> {
        const access = new Accessor(this.product);

        return access.calc();
    }
}

我想用Jest编写一个测试,它基本上测试调度程序。

beforeEach(() => {
    clock = sinon.usefaketimers();
    cut = new ExportScheduler(
       '* * * * *',product
    );
   });

it('should schedule exports',async () => {
    expect(await cut.export).not.toHaveBeenCalled();
    clock.tick(70000);
    expect(await cut.export).toHaveBeenCalledTimes(1);
}

但是它告诉我以下内容

匹配器错误:接收到的值必须是模拟或间谍函数

我应该如何测试此调度程序。

解决方法

您应该在此处使用jest全局对象。

模拟CRON计时器

  • 使用jest.useFakeTimers()使Jest使用标准计时器功能的伪造版本。根据{{​​3}},您需要将字符串参数"modern"传递给它,以便模拟通常由CRON调度程序使用的类似Date的计时器。
  • 使用this issue以毫秒为单位快进计时器。
  • 使用jest.advanceTimersByTime()清除所有已安排(但尚未执行)的计时器。

监视类方法

let cut

beforeEach(() => {
    jest.useFakeTimers('modern')

    cut = new ExportScheduler('* * * * *',product);
});

afterEach(() => {
    jest.clearAllTimers();
})

it('does not invoke .export(),before 60 seconds have passed',() => {
    const exportSpy = jest.spyOn(cut,'export');

    jest.advanceTimersByTime(50000);

    expect(exportSpy).not.toBeCalled();
}

it('invokes .export() once,after 60 seconds have passed','export');

    jest.advanceTimersByTime(60000);

    expect(exportSpy).toHaveBeenCalledTimes(1);
}

请注意,您实际上不需要使用异步,因为您只是断言该方法已被调用。在此示例中,仅当计划声明.export()的已解决承诺的值时,才希望使测试异步。