如何开玩笑地模拟和避免 express-validator 调用?
How to mock and avoid express-validator calls in jest?
我们的代码库中有如下代码:
@Validate(Param1)
async post(request, responseHandler) {
// some code
}
我正在尝试测试 post 函数。但要避免评估 @Validate
函数。 Validate
是另一个模块中的函数。
// validator.ts
export const Validate = () => {
// some code
}
怎么办? .
您可以使用 jest.mock(moduleName, factory, options) 创建模拟的 Validate
装饰器,而不是使用可能有很多验证规则的真实 Validate
装饰器。
例如
index.ts
:
import { Validate } from './validator';
export class Controller {
@Validate('params')
async post(request, responseHandler) {
console.log('real post implementation');
}
}
validator.ts
:
export const Validate = (params) => {
return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
const oFunc = descriptor.value;
descriptor.value = function inner(...args: any[]) {
console.log('real validator decorator implementation');
// lots of validation
const rval = oFunc.apply(this, args);
return rval;
};
};
};
index.test.ts
:
import { Validate } from './validator';
import { mocked } from 'ts-jest/utils';
jest.mock('./validator');
describe('63531414', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should pass', async () => {
mocked(Validate).mockImplementationOnce((params) => {
return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
const oFunc = descriptor.value;
descriptor.value = function inner(...args: any[]) {
console.log('mocked validator decorator implementation');
const rval = oFunc.apply(this, args);
return rval;
};
};
});
const { Controller } = require('./');
const logSpy = jest.spyOn(console, 'log');
const ctrl = new Controller();
await ctrl.post({}, () => {});
expect(Validate).toBeCalledWith('params');
expect(logSpy).toBeCalledWith('real post implementation');
});
});
带有覆盖率报告的单元测试结果:
PASS src/Whosebug/63531414/index.test.ts (12.634s)
63531414
✓ should pass (154ms)
console.log node_modules/jest-mock/build/index.js:860
mocked validator decorator implementation
console.log node_modules/jest-mock/build/index.js:860
real post implementation
--------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files | 45.45 | 100 | 25 | 45.45 | |
index.ts | 100 | 100 | 100 | 100 | |
validator.ts | 14.29 | 100 | 0 | 14.29 | 2,3,4,5,7,8 |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.354s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/Whosebug/63531414
我们的代码库中有如下代码:
@Validate(Param1)
async post(request, responseHandler) {
// some code
}
我正在尝试测试 post 函数。但要避免评估 @Validate
函数。 Validate
是另一个模块中的函数。
// validator.ts
export const Validate = () => {
// some code
}
怎么办? .
您可以使用 jest.mock(moduleName, factory, options) 创建模拟的 Validate
装饰器,而不是使用可能有很多验证规则的真实 Validate
装饰器。
例如
index.ts
:
import { Validate } from './validator';
export class Controller {
@Validate('params')
async post(request, responseHandler) {
console.log('real post implementation');
}
}
validator.ts
:
export const Validate = (params) => {
return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
const oFunc = descriptor.value;
descriptor.value = function inner(...args: any[]) {
console.log('real validator decorator implementation');
// lots of validation
const rval = oFunc.apply(this, args);
return rval;
};
};
};
index.test.ts
:
import { Validate } from './validator';
import { mocked } from 'ts-jest/utils';
jest.mock('./validator');
describe('63531414', () => {
afterAll(() => {
jest.resetAllMocks();
});
it('should pass', async () => {
mocked(Validate).mockImplementationOnce((params) => {
return (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) => {
const oFunc = descriptor.value;
descriptor.value = function inner(...args: any[]) {
console.log('mocked validator decorator implementation');
const rval = oFunc.apply(this, args);
return rval;
};
};
});
const { Controller } = require('./');
const logSpy = jest.spyOn(console, 'log');
const ctrl = new Controller();
await ctrl.post({}, () => {});
expect(Validate).toBeCalledWith('params');
expect(logSpy).toBeCalledWith('real post implementation');
});
});
带有覆盖率报告的单元测试结果:
PASS src/Whosebug/63531414/index.test.ts (12.634s)
63531414
✓ should pass (154ms)
console.log node_modules/jest-mock/build/index.js:860
mocked validator decorator implementation
console.log node_modules/jest-mock/build/index.js:860
real post implementation
--------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files | 45.45 | 100 | 25 | 45.45 | |
index.ts | 100 | 100 | 100 | 100 | |
validator.ts | 14.29 | 100 | 0 | 14.29 | 2,3,4,5,7,8 |
--------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 14.354s
源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/Whosebug/63531414