如何使用带有 TypeScript 的 jest 来模拟第三方 nodejs 模块函数? [英] How can I mock a third-party nodejs module function using jest with TypeScript?

查看:16
本文介绍了如何使用带有 TypeScript 的 jest 来模拟第三方 nodejs 模块函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用玩笑模拟第三方节点模块中的函数,特别是 fs.readFileSync() 函数.有很多例子,但我还没有找到一个使用 TypeScript 的例子.我在 github 上有一个简单的、希望最小的示例.对于熟悉 Jest 的人来说,这可能是一个简单的问题.

I am trying to mock a function in a third-party node module, specifically the fs.readFileSync() function, using jest. There are quite a few examples out there but I haven't found one which uses TypeScript. I have a simple, hopefully minimal, example at github. This is probably a simple issue for someone familiar with jest.

推荐答案

这里有几种不同的模拟fs.readFileSync()之类的方法:

Here are a few different ways of mocking something like fs.readFileSync():

模拟函数

要模拟函数,请使用 jest.spyOn()mockImplementation():

To mock a function use jest.spyOn() in combination with functions like mockImplementation():

import { returnNameInJsonFile } from './index';
import * as fs from 'fs';

describe('index', () => {

  it('returnNameInJsonFile', () => {
    const mock = jest.spyOn(fs, 'readFileSync');  // spy on fs.readFileSync()
    mock.mockImplementation(() => JSON.stringify({ name: 'myname' }));  // replace the implementation

    const name: string = returnNameInJsonFile('test.json');
    expect(name).toBe('myname');

    mock.mockRestore();  // restore fs.readFileSync()
  });

});

<小时>

使用工厂模拟模块

模块工厂传递给jest.mock():

import { returnNameInJsonFile } from './index';

jest.mock('fs', () => {
  const MOCK_FILE_INFO = { 'test.json': JSON.stringify({ name: 'myname' }) };
  return {
    readFileSync: (fpath, opts) => {
      if (fpath in MOCK_FILE_INFO) {
        return MOCK_FILE_INFO[fpath]
      }
      throw 'unexpected fpath'
    }
  }
});

describe('index', () => {
  it('returnNameInJsonFile', () => {
    const name: string = returnNameInJsonFile('test.json');
    expect(name).toBe('myname'); // 1.0.0 is installed and 2.0.0 is available
  });
});

<小时>

自动模拟模块

创建模块的模拟.

Jest 将自动使用模拟,除非它是一个核心 Node 模块(如 fs),在这种情况下 需要调用jest.mock().

Jest will use the mock automatically unless it is a core Node module (like fs) in which case calling jest.mock() is required.

__mocks__/fs.ts:

__mocks__/fs.ts:

const fs = jest.genMockFromModule('fs');

let mockFiles: object = {};

function __setMockFiles (newMockFiles: object) {
  mockFiles = newMockFiles;
}

function readFileSync(filePath: string) {
  return mockFiles[filePath] || '';
}

// If anyone knows how to avoid the type assertion feel free to edit this answer
(fs as any).__setMockFiles = __setMockFiles;
(fs as any).readFileSync = readFileSync;

module.exports = fs;

index.test.ts:

index.test.ts:

import { returnNameInJsonFile } from './index';

jest.mock('fs');  // Required since fs is a core Node module

describe('index', () => {

  const MOCK_FILE_INFO = { 'test.json': JSON.stringify({ name: 'myname' }) };

  beforeEach(() => {
    require('fs').__setMockFiles(MOCK_FILE_INFO);
  });

  it('returnNameInJsonFile', () => {
    const name: string = returnNameInJsonFile('test.json');
    expect(name).toBe('myname'); // 1.0.0 is installed and 2.0.0 is available
  });
});

这篇关于如何使用带有 TypeScript 的 jest 来模拟第三方 nodejs 模块函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆