0

I'd like to test Module2 constructor as well as other its functions. What is the proper way to mock Module2 constructor without breaking testFunc1, testFunc2 to test with 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() 
7
  • Why do you think you need to mock the Module2 constructor? What test case do you have in mind, can you add the code for that? Commented Apr 14, 2021 at 22:24
  • just for test coverage... I need to test try/catch block.. e.g. if init() throws an error then catch block should be executed Commented Apr 14, 2021 at 22:59
  • So you're asking to test the Module2 constructor (by mocking module1.init and process.exit), not to mock it? Commented Apr 14, 2021 at 23:01
  • yes. .test the constructor.. .so probably module1.init() needs to be mocked. Anyway I need to cover constructor with unittest Commented Apr 14, 2021 at 23:18
  • Yes, mock the module1.init() call, once with a no-op once with a throwing function, and test your constructor to behave accordingly. Commented Apr 14, 2021 at 23:29

1 Answer 1

2

You are testing module2, so you need to mock module1 rather than module2.

You can use jest.doMock(moduleName, factory, options) to mock module1 module. After mocking, require the module2. Besides, you should use jest.resetModules() to reset the module cache from require.cache object before mocking with different implementations.

E.g.

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); }); }); 

unit test result:

 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 
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you Mr. slideshowp2.. That works perfect and that's what I need. I had to try to move require() part

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.