问题描述
我知道您可以模拟并监视函数内部的函数调用,例如使用jest.spyOn和jest.fn()... .toHaveBeenCalledTimes(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
});
})
解决方法
开玩笑的间谍功能相对适中。 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);
});