如何模拟摩卡中的全局变量?

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]);
  });
});