【问题标题】:how properly mock/test constructor with Jest用 Jest 如何正确地模拟/测试构造函数
【发布时间】:2021-04-15 10:04:49
【问题描述】:

我想测试 Module2 的构造函数以及它的其他函数。在不破坏 testFunc1、testFunc2 的情况下模拟 Module2 构造函数以使用 Jest 进行测试的正确方法是什么。

// ****************************************
// Module 1 component
class Module1 {
  init() {
    // ........
  }
}

module.exports = new Module1()


// ****************************************
// Module 2 component
const module1 = require('./module1')

class Module2 {
  constructor() {
    try {
      module1.init()
    } catch (err) {
      console.log('error')
      process.exit(1)
    }
  }

  testfunc1 = () => {
    // ........
  }

  testfunc2 = () => {
    // ........
  }
}

module.exports = new Module2()

【问题讨论】:

  • 为什么你认为你需要模拟 Module2 构造函数?你有什么测试用例,你能添加代码吗?
  • 只是为了测试覆盖率......我需要测试 try/catch 块......例如如果 init() 抛出错误,则应该执行 catch 块
  • 所以您要求测试 Module2 构造函数(通过模拟module1.initprocess.exit),而不是模拟它?
  • 是的。 .test 构造函数.. 所以可能 module1.init() 需要被模拟。无论如何,我需要用 unittest 覆盖构造函数
  • 是的,模拟 module1.init() 调用,一次使用无操作一次使用抛出函数,并测试您的构造函数以使其行为相应。

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


【解决方案1】:

您正在测试module2,因此您需要模拟module1 而不是module2

您可以使用jest.doMock(moduleName, factory, options) 模拟module1 模块。嘲讽后,requiremodule2。此外,在使用不同的实现进行模拟之前,您应该使用jest.resetModules()require.cache 对象重置模块缓存。

例如

module1.js:

class Module1 {
  init() {}
}

module.exports = new Module1();

module2.js:

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

class Module2 {
  constructor() {
    try {
      module1.init();
    } catch (err) {
      console.log('error');
      process.exit(1);
    }
  }

  testfunc1 = () => {};

  testfunc2 = () => {};
}

module.exports = new Module2();

module2.test.js:

describe('67099526', () => {
  beforeEach(() => {
    jest.resetModules();
  });
  it('should initialize module1 correctly', () => {
    const module1instance = { init: jest.fn() };
    jest.doMock('./module1', () => {
      return module1instance;
    });
    require('./module2');
    expect(module1instance.init).toBeCalledTimes(1);
  });

  it('should handle error', () => {
    const exitSpy = jest.spyOn(process, 'exit').mockImplementation();
    const module1instance = {
      init: jest.fn().mockImplementationOnce(() => {
        throw new Error('initialize module1');
      }),
    };
    jest.doMock('./module1', () => {
      return module1instance;
    });
    require('./module2');
    expect(module1instance.init).toBeCalledTimes(1);
    expect(exitSpy).toBeCalledWith(1);
  });
});

单元测试结果:

 PASS  examples/67099526/module2.test.js (11.508 s)
  67099526
    ✓ should initialize module1 correctly (8819 ms)
    ✓ should handle error (18 ms)

  console.log
    error

      at new Module2 (examples/67099526/module2.js:8:15)

------------|---------|----------|---------|---------|-------------------
File        | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
------------|---------|----------|---------|---------|-------------------
All files   |     100 |      100 |   33.33 |     100 |                   
 module2.js |     100 |      100 |   33.33 |     100 |                   
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        13.743 s

【讨论】:

  • 谢谢slideshowp2先生。这很完美,这就是我所需要的。我不得不尝试移动 require() 部分
猜你喜欢
  • 2018-09-27
  • 1970-01-01
  • 2020-01-08
  • 2020-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
相关资源
最近更新 更多