我有一项服务,可以通过配置触发的替代行为来装饰异步功能:
// decorator.js
const config = require('./config');
const logger = require('./logger');
function addAlternateBehavior(originalAsyncFunction, alternateAsyncFunction) {
return async () => {
if (config.useAlternateBehavior) {
await alternateAsyncFunction();
} else {
await originalAsyncFunction();
}
logger.info('Behavior finished executing');
};
}
exports.addAlternateBehavior = addAlternateBehavior;
我有一个Jest单元测试,可以验证相应配置后是否调用了替代行为:
// decorator.test.js
const decorator = require('./decorator');
const config = require('./config');
it('returned function should use alternate behavior when configured to do so', async () => {
// Arrange
const originalAsyncFunction = jest.fn();
const alternateAsyncFunction = jest.fn();
config.useAlternateBehavior = true;
// Act
const decoratedFunction = decorator
.addAlternateBehavior(originalAsyncFunction, alternateAsyncFunction);
await decoratedFunction();
// Assert
expect(originalAsyncFunction.mock.calls.length).toBe(0);
expect(alternateAsyncFunction.mock.calls.length).toBe(1);
});
我想断言,当您使用await
调用修饰的函数时,它也会等待预期的行为。但是,在装饰器中,如果我将await alternateAsyncFunction();
更改为alternateAsyncFunction()
,则我的单元测试仍然可以通过。
在单元测试中,如何断言由addAlternateBehavior()
装饰的函数正在等待alternateAsyncFunction
或originalAsyncFunction
?
答案 0 :(得分:1)
赋予您的async
函数一个实现,该实现至少等待两个事件循环,然后再调用内部mock
。然后测试内部mock
是否被调用:
const decorator = require('./decorator');
const config = require('./config');
it('returned function should use alternate behavior when configured to do so', async () => {
// Arrange
const originalInner = jest.fn();
const originalAsyncFunction = jest.fn(async () => {
await Promise.resolve();
await Promise.resolve();
originalInner();
});
const alternateInner = jest.fn();
const alternateAsyncFunction = jest.fn(async () => {
await Promise.resolve();
await Promise.resolve();
alternateInner();
});
config.useAlternateBehavior = true;
// Act
const decoratedFunction = decorator
.addAlternateBehavior(originalAsyncFunction, alternateAsyncFunction);
await decoratedFunction();
// Assert
expect(originalAsyncFunction.mock.calls.length).toBe(0);
expect(originalInner.mock.calls.length).toBe(0);
expect(alternateAsyncFunction.mock.calls.length).toBe(1);
expect(alternateInner.mock.calls.length).toBe(1);
});
如果addAlternateBehavior()
创建的函数没有await
,则内部mock
不会被调用。
请注意,有两个await Promise.resolve();
语句是必需的,因为第一个在await decoratedFunction();
的事件循环周期内会解决