如何模拟摩卡中的全局变量?
how to mock a global variable in mocha?
我有一个包含以下代码的文件:
在file.ts中:
let gateways = new Map<string, Set<number>>();
export const handler = async (event: any = {}): Promise<any> => {
let gws: Set<number> | undefined = gateways.get(action);
console.log(gws)
return gws
}
gateways 变量被实例化并通过不同的机制设置一个值。
我正在为处理程序函数编写单元测试,需要模拟 gateways
变量,以便它 returns 调用 gateways.get()
时的模拟值。
有什么办法可以做到这一点??我尝试使用 rewire
模块,但它不起作用。
单元测试用例:
import * as mocha from 'mocha'
import {Substitute, Arg} from '@fluffy-spoon/substitute'
import {handler} from './helpers'
import rewire from 'rewire'
const helper = rewire('./helpers')
helper.__set__('gateways', [1, 2, 3, 4, 5, 6, 7, 8])
describe('test', () => {
before(() => {
})
it('testing handler', () => {
const result = handler('')
})
})
因为 gateway
变量实际上不是 global
(它只是 file.ts
-模块中的 "global"),你不能直接从外部模拟它(我还没有使用 rewire,也许它会允许它)。但是有一种更简单的方法可以做到这一点而不必依赖额外的库:
如何将您的 handler
函数包装在 class 中并定义一个方法来封装对 Map
的访问?在您的单元测试中,您可以简单地 overwrite/mock 此方法的行为。类似于:
export class EventHandler {
private gateways = new Map<string, Set<number>>();
async handler (event: any = {}): Promise<any> {
// obtain action
const action = await ...;
const gws: Set<number> | undefined = this.getAction(action);
console.log(gws)
return gws;
}
getAction(action) {
return this.gateways.get(action);
}
}
然后在您的单元测试中,您可以简单地手动覆盖 getAction
或使用 Sinon 创建一个存根。以下是您手动执行此操作的方法:
describe('EventHandler', () => {
it('handler should correctly return values', async () => {
const eventHandler = new EventHandler();
// mock behaviour of `getAction`
eventHandler.getAction = () => [1, 2, 3, 4, 5, 6, 7, 8];
const result = await eventHandler.handler('');
expect(result).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
});
});
在您的单元测试中,您可以简单地手动覆盖 getAction 或使用 Sinon 创建存根。以下是您手动执行此操作的方法:
describe('EventHandler', () => {
it('handler should correctly return values', async () => {
const eventHandler = new EventHandler();
// mock behaviour of `getAction`
eventHandler.getAction = () => [1, 2, 3, 4, 5, 6, 7, 8];
const result = await eventHandler.handler('');
expect(result).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
});
});
我有一个包含以下代码的文件:
在file.ts中:
let gateways = new Map<string, Set<number>>();
export const handler = async (event: any = {}): Promise<any> => {
let gws: Set<number> | undefined = gateways.get(action);
console.log(gws)
return gws
}
gateways 变量被实例化并通过不同的机制设置一个值。
我正在为处理程序函数编写单元测试,需要模拟 gateways
变量,以便它 returns 调用 gateways.get()
时的模拟值。
有什么办法可以做到这一点??我尝试使用 rewire
模块,但它不起作用。
单元测试用例:
import * as mocha from 'mocha'
import {Substitute, Arg} from '@fluffy-spoon/substitute'
import {handler} from './helpers'
import rewire from 'rewire'
const helper = rewire('./helpers')
helper.__set__('gateways', [1, 2, 3, 4, 5, 6, 7, 8])
describe('test', () => {
before(() => {
})
it('testing handler', () => {
const result = handler('')
})
})
因为 gateway
变量实际上不是 global
(它只是 file.ts
-模块中的 "global"),你不能直接从外部模拟它(我还没有使用 rewire,也许它会允许它)。但是有一种更简单的方法可以做到这一点而不必依赖额外的库:
如何将您的 handler
函数包装在 class 中并定义一个方法来封装对 Map
的访问?在您的单元测试中,您可以简单地 overwrite/mock 此方法的行为。类似于:
export class EventHandler {
private gateways = new Map<string, Set<number>>();
async handler (event: any = {}): Promise<any> {
// obtain action
const action = await ...;
const gws: Set<number> | undefined = this.getAction(action);
console.log(gws)
return gws;
}
getAction(action) {
return this.gateways.get(action);
}
}
然后在您的单元测试中,您可以简单地手动覆盖 getAction
或使用 Sinon 创建一个存根。以下是您手动执行此操作的方法:
describe('EventHandler', () => {
it('handler should correctly return values', async () => {
const eventHandler = new EventHandler();
// mock behaviour of `getAction`
eventHandler.getAction = () => [1, 2, 3, 4, 5, 6, 7, 8];
const result = await eventHandler.handler('');
expect(result).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
});
});
在您的单元测试中,您可以简单地手动覆盖 getAction 或使用 Sinon 创建存根。以下是您手动执行此操作的方法:
describe('EventHandler', () => {
it('handler should correctly return values', async () => {
const eventHandler = new EventHandler();
// mock behaviour of `getAction`
eventHandler.getAction = () => [1, 2, 3, 4, 5, 6, 7, 8];
const result = await eventHandler.handler('');
expect(result).to.eql([1, 2, 3, 4, 5, 6, 7, 8]);
});
});