在Jest中,在测试模块中模拟用户模块中的Node模块

时间:2019-07-25 17:30:39

标签: javascript node.js unit-testing mocking jestjs

我有一个名为files.js的用户模块。它使用globby节点模块,如下所示:

const globby = require('globby');

module.exports = {
  /**
   * Get the paths for files in the current directory.
   * 
   * @returns {Promise<string[]>} The file paths.
   */
  async getFiles() {
    return await globby(__dirname);
  },
};

我有一个files.test.js测试文件,如下所示:

const globby = require('globby');
const path = require('path');

const files = require('./files');

describe('files', () => {
  test('get files', async () => {
    const items = await files.getFiles();

    // The files that we expect are the ones in the current directory. Prepend
    // the current directory to each filename, so that they are absolute paths.
    const expectedFiles = ['files.js', 'files.test.js'];
    const expected = expectedFiles.map((file) => path.join(__dirname, file));

    expect(items).toEqual(expected);
  });

  test('get files (mocked)', async () => {
    // Try to mock the `globby` module.
    jest.mock('globby');

    globby.mockResolvedValue(['Test.js']);

    // Get the files, but expect the mocked value that we just set.
    const items = await files.getFiles();

    expect(items).toEqual(['Test.js']);
  });
});

第一次测试通过,但是第二次测试失败,因为globby的解析值无法正确模拟。我已经使用jest.mockjest.doMock等进行了尝试,但是我无法正确模拟globby的值,因此它在对{的调用中返回['Test.js'] globby中的{1}}。

如何正确模拟getFiles的解析值,以便它在单个测试块中从globby返回我想要的值?

此刻,我只是将测试分为两个文件,一个文件包含需要getFiles的测试的模拟,另一个文件包含需要globby的测试的模拟,但是我希望有一个更优雅的解决方案,可以在同一文件中完成所有操作。

1 个答案:

答案 0 :(得分:0)

我想到的一个解决方案是:

const path = require('path');

let files = require('./files');

describe('files', () => {
  beforeEach(() => {
    jest.resetModules();
  });

  test('get files', async () => {
    const items = await files.getFiles();

    // The files that we expect are the ones in the current directory. Prepend
    // the current directory to each filename, so that they are absolute paths.
    const expectedFiles = ['files.js', 'files.test.js'];
    const expected = expectedFiles.map((file) => path.join(__dirname, file));

    expect(items).toEqual(expected);
  });

  test('get files (mocked)', async () => {
    jest.doMock('globby');

    const globby = require('globby');
    files = require('./files');

    globby.mockResolvedValue(['Test.js']);

    // Get the files, but expect the mocked value that we just set.
    const items = await files.getFiles();

    expect(items).toEqual(['Test.js']);
  });
});