【问题标题】:CommonJS and Jest Mocking - Exported Function not being mockedCommonJS 和 Jest 模拟 - 导出的函数未被模拟
【发布时间】:2020-07-27 15:12:36
【问题描述】:

我在使用 commonjs 模拟我的模块中的特定函数时遇到问题

示例模块db.js

function createDefaultProfile(user_id) {
 return { version: 1, username: user_id };
}

function updateOrCreateProfile(user_id, profile) {
  if (profile && profile.credential_id) return null; //no need to update
  if (!profile) profile = createDefaultProfile(user_id);
  if (!profile.credential_id) {
    //update profile with key
  }

module.exports = {createDefaultProfile, updateOrCreateProfile }

示例测试文件尝试1:

describe("updateOrCreateUser()", () => {
  const db = require('../db.js')

  it("should call createDefaultProfile() when no profile is provided", () => {
    db.createDefaultProfile = jest.fn()
    db.updateOrCreateProfile(userID)
    expect(db.createDefaultProfile).toHaveBeenCalledTimes(1)
  })
})

示例测试文件尝试2:

describe("updateOrCreateUser()", () => {
  jest.mock('../db', () => {
    // Require the original module to not be mocked...
    const originalModule = jest.requireActual('../db');

    return {
      __esModule: true, // Use it when dealing with esModules
      ...originalModule,
      createDefaultProfile: jest.fn().mockReturnValue('arbitrary value'),
    }
  })

  const db = require('../db.js')

  it("should call createDefaultProfile() when no profile is provided", () => {
    db.updateOrCreateProfile(userID)
    expect(db.createDefaultProfile).toHaveBeenCalledTimes(1)
  })
})

两者都返回错误的值,因为模拟模块永远不会被调用.. 在这两种情况下,模拟模块的范围似乎都不正确......

【问题讨论】:

    标签: javascript testing jestjs commonjs


    【解决方案1】:

    updateOrCreateProfile 函数中调用的createDefaultProfile 函数是原始的,而不是您尝试用jest.fn() 替换的模拟函数。试试下面:

    db.js:

    function createDefaultProfile(user_id) {
      return { version: 1, username: user_id };
    }
    
    function updateOrCreateProfile(user_id, profile) {
      if (profile && profile.credential_id) return null;
      if (!profile) profile = exports.createDefaultProfile(user_id);
      if (!profile.credential_id) {
        console.log('update profile with key');
      }
    }
    
    exports.createDefaultProfile = createDefaultProfile;
    exports.updateOrCreateProfile = updateOrCreateProfile;
    

    db.test.js:

    describe('63118259', () => {
      describe('updateOrCreateUser', () => {
        const db = require('./db.js');
        it('should call createDefaultProfile() when no profile is provided', () => {
          const userID = 1;
          const logSpy = jest.spyOn(console, 'log');
          db.createDefaultProfile = jest.fn().mockReturnValueOnce({ credential_id: null });
          db.updateOrCreateProfile(userID);
          expect(db.createDefaultProfile).toHaveBeenCalledTimes(1);
          expect(logSpy).toBeCalledWith('update profile with key');
        });
      });
    });
    

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

     PASS  stackoverflow/63118259/db.test.js (10.819s)
      63118259
        updateOrCreateUser
          ✓ should call createDefaultProfile() when no profile is provided (26ms)
    
      console.log
        update profile with key
    
          at CustomConsole.<anonymous> (node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866:25)
    
    ----------|---------|----------|---------|---------|-------------------
    File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
    ----------|---------|----------|---------|---------|-------------------
    All files |   77.78 |       50 |      50 |   85.71 |                   
     db.js    |   77.78 |       50 |      50 |   85.71 | 2                 
    ----------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests:       1 passed, 1 total
    Snapshots:   0 total
    Time:        12.367s
    

    【讨论】:

    • 在本地仍然无法为我工作。这倾向于我的 jest 安装无法正常工作的可能性。
    猜你喜欢
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 2018-09-14
    相关资源
    最近更新 更多