使用Jest.js模拟复杂模块

时间:2018-08-06 08:45:32

标签: javascript jestjs web3

这就是我要模拟的模块的样子:

class TheModule {
  constructor() {
    this.subClass = new SubClass();
  }
}

class SubClass {
  constructor() {
    this.someMethod = () => 'Did Something great'; 
  }
}

module.exports = TheModule;

这是我要测试的TheModule用法:

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

const method = () => {
  const theModule = new TheModule();
  return theModule.subClass.someMethod();
}

module.exports = method;

这是我的测试:

describe('method test', () => {

  it('should return "Test pass"', () => {
    jest.doMock('./TheModule');
    const theModuleMock = require('./TheModule');
    const method = require('./TheModuleUsage');
    const mock = () => 'Test pass';
    theModuleMock.subClass.someMethod.mockImplementation(() => mock);
    expect(method()).toEqual('Test pass');
  });

});

运行此测试时,我得到TypeError: Cannot read property 'someMethod' of undefined

是否可以模拟此模块(无需更改TheModule实现)?

1 个答案:

答案 0 :(得分:0)

如果您要导出SubClass,则可以在不更改TheModule的情况下对其进行模拟,但例如,您应该使用工厂显式地对SubClass中的TheModule属性进行模拟:

describe('method test', () => {

  it('should return "Test pass"', () => {
    let mockedSomeMethod = jest.fn().mockImplementation(() => 'Test pass');
    jest.doMock('./TheModule', () => {
      // mock constructor
      return jest.fn().mockImplementation(() => {
        return { subClass: { someMethod: mockedSomeMethod  } }
      });
    });
    const method = require('./TheModuleUsage');
    expect(method()).toEqual('Test pass');
  });
});