javascript - 在 Jest 测试中模拟节点模块

标签 javascript unit-testing testing jestjs

我有一个 Jest 测试,我正在为一个调用 API 的函数编写。如果 API 调用返回 403,则应调用节点模块中的函数。我正在尝试使用模拟 Jest 函数对此进行测试,但我无法通过测试来使用我正在制作的模块的模拟版本。

文件.spec.js

import file from './file'

const mockedNodeModule = jest.genMockFromModule('nodeModule')
mockedNodeModule.namedExport = { logout: jest.fn() }

it('call returns a 403', async () => {
      await file.apiCall('brand', 'entityType', 'name')
      expect(mockedNodeModule.namedExport.logout).toHaveBeenCalled()
})

文件.js

import { namedExport } from './nodeModule';
import api from './api';

const apiCall = () => {
  return api.makeCall().then(
    () => {},
    (error) => {
      if (error.status === 403) {
        namedExport.logout();
      }
    },
  );
};

export default { apiCall };

当我检查是否调用了 mockedNodeModule.namedExport.logout 时,测试总是失败。当我在调用它的行上放置一个断点时,似乎在测试运行时没有使用模拟版本(即它仍在使用我的 node_modules 中的模块)。我也尝试过使用 jest.mock() ,但结果是一样的。我设置测试的方式有问题吗?在这种情况下,开 Jest 不能模拟节点模块吗?

最佳答案

jest.mock(moduleName, factory, options)应该管用。

例如

文件.js:

import { namedExport } from './nodeModule';
import api from './api';

const apiCall = () => {
  return api.makeCall().then(
    () => {},
    (error) => {
      if (error.status === 403) {
        namedExport.logout();
      }
    },
  );
};

export default { apiCall };

api.js:

function makeCall() {}

export default { makeCall };

nodeModule.js:

export const namedExport = {
  logout() {
    console.log('real implementation');
  },
};

file.test.js:

import file from './file';
import api from './api';
import { namedExport } from './nodeModule';

jest.mock('./nodeModule', () => {
  const mNamedExport = {
    logout: jest.fn(),
  };
  return { namedExport: mNamedExport };
});

jest.mock('./api', () => {
  return { makeCall: jest.fn() };
});

describe('59831697', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  it('should handle error if http status equal 403', async () => {
    const mError = { status: 403 };
    api.makeCall.mockRejectedValueOnce(mError);
    await file.apiCall();
    expect(namedExport.logout).toHaveBeenCalledTimes(1);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59831697/file.test.js (13.506s)
  59831697
    ✓ should handle error if http status equal 403 (7ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |       50 |    66.67 |      100 |                   |
 file.js  |      100 |       50 |    66.67 |      100 |                 8 |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        15.448s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59831697

关于javascript - 在 Jest 测试中模拟节点模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59831697/

相关文章:

ruby-on-rails-3 - 使用 capybara 和 delayed_job 测试电子邮件

testing - Go 中测试负面场景的方法

JUNIT 测试时出现 java.lang.StackOverflowError

javascript - 使用 JavaScript 或 jQuery 自动填充当前时间

Matlab 从 XUnit 迁移到 Matlab 2013 单元测试

javascript - 将 Flow 用于浏览器应用程序

java - 跳过maven中的测试用例执行甚至不编译测试用例

unit-testing - Groovy-grails 模拟问题。无法模拟

javascript - AngularJS ng-repeat 上的系列

javascript - Backbone : Creating multiple models in a collection from a nested object