是否有一个Jest函数,禁止任何其他超出预期的函数调用



我知道你可以模拟和监视函数内部的函数调用,例如使用jest.spyOn和jest.fn((……toHaveBeenColledTimes(1(等。在Spock框架测试中,你可以用结束单元测试

0*_//不允许任何其他交互

有没有办法通过Jest实现这一点?

示例:

export default class Service {
public startAllWorkers(): void {
const processClient: ProcessClient = new ProcessClient();
const processMonitor: ProcessMonitor = new ProcessMonitor();
const defaultValue: number = 10;
processClient.runClient(defaultValue);
processMonitor.runMonitor('pling')
}
}

describe('Service test', () => {
let service: Service;
beforeEach(() => {
service = new Service();
ProcessClient.prototype.runClient = jest.fn()
ProcessMonitor.prototype.runMonitor = jest.fn()
});
it('should only call specific methods', () => {
const spyService = jest.spyOn(service, 'startAllWorkers');
service.startAllWorkers();
expect(spyService).toHaveBeenCalledTimes(1);
expect(ProcessClient.prototype.runClient).toHaveBeenCalledTimes(1);
expect(ProcessMonitor.prototype.runMonitor).toHaveBeenCalledTimes(1);
// expect no other interactions inside service method
});
})

Jest间谍功能相对较弱。toBeCalledWith断言允许检查是否使用指定的参数进行了其中一个调用。

需要明确断言更具体的调用:

// fn('foo', 1);
// fn('bar', 2);
expect(mockFn).toBeCalledTimes(2); // redundant but provides human readable output
expect(mockFn.mock.calls).toEqual([
['foo', 1]
['bar', expect.any(Number)]
]);

如果一个函数不是连续调用的,可以很快断言一个间谍,以不允许意外调用:

// fn('foo', 1);
expect(mockFn).toBeCalledTimes(1);
expect(mockFn).toBeCalledWith('foo', 1);
mockFn.mockClear();
...
// fn('bar', 2);
expect(mockFn).toBeCalledTimes(1);
expect(mockFn).toBeCalledWith('bar', 2);
mockFn.mockClear();
...
expect(mockFn).not.toBeCalled();

或者,智能间谍可以负责实现和预期用途:

mockFn.mockImplementation((...args) => {
// first call
if (mockFn.mock.calls.length === 1) {
expect(args).toEqual(...);
return ...;
}
// second call
if (mockFn.mock.calls.length === 2) {
expect(args).toEqual(...);
return ...;
}
// no more calls
expect(mockFn.mock.calls.length).not.toBe(3);
});

最新更新