如何处理模块和打字稿类型的jest模拟函数

时间:2017-07-06 06:52:23

标签: javascript typescript jestjs

我使用ts-jestjest来编写带有typescript的测试文件。

我很困惑如何输入模块的模拟功能。

这是我的代码:

./module.ts

import {IObj} from '../interfaces';

const obj: IObj = {
  getMessage() {
    return `Her name is ${this.genName()}, age is ${this.getAge()}`;
  },

  genName() {
    return 'novaline';
  },

  getAge() {
    return 26;
  }
};

export default obj;

./module.test.ts

import * as m from './module';

describe('mock function test suites', () => {

  it('t-1', () => {
    // I think the jest.Mock<string> type here is not correct.
    m.genName: jest.Mock<string> = jest.fn(() => 'emilie'); 
    expect(jest.isMockFunction(m.genName)).toBeTruthy();
    expect(m.genName()).toBe('emilie');
    expect(m.getMessage()).toEqual('Her name is emilie, age is 26');
    expect(m.genName).toHaveBeenCalled(); 

  });

});

如何输入模块genName的模拟函数m

typescript在这里给我一个错误:

  

错误:(8,7)TS2540:无法分配给'genName',因为它是常量或只读属性。

5 个答案:

答案 0 :(得分:1)

我在嘲笑它:

jest.mock('./module')
const {genName} = require('./module')

在我的测试中:

 genName.mockImplementationOnce(() => 'franc')

对我来说很好,没有打字稿错误

答案 1 :(得分:1)

这是我解决相同问题的方式,也是我现在进行所有嘲笑和间谍的方式。

import * as m from './module';

describe('your test', () => {
  let mockGenName;

  beforeEach(() => {
    mockGenName = jest.spyOn(m, 
      'genName').mockImplemetation(() => 'franc');
  })

  afterEach(() => {
    mockGenName.mockRestore();
  })


  test('your test description', () => {
    // do something that calls the genName function
    expect(mockGenName).toHaveBeenCalledTimes(1);
  })

})

使用此设置,您可以以编程方式更改针对不同测试的模拟的实现,然后断言该函数已被调用以及调用该函数的方式,同时在测试之间和所有测试之后清除模拟。

答案 2 :(得分:0)

您想要模拟模块,然后更改其中的导出函数。这应该替换你的import语句。

jest.mock('./module', () => ({
    genName: jest.fn().mockImplementation(() => 'emilie')
}))

答案 3 :(得分:0)

import * as m from './module'

jest.mock('./module', () => ({
    genName: jest.fn().mockImplementation(() => 'emilie')
    // will return "enilie" for all tests
}))

it('returns franc', () => {
  m.genName.mockImplementationOnce(() => 'franc')
  // will return "franc" for this particular test
})

答案 4 :(得分:0)

我得到错误的原因是:

模块对象foo的属性(从foo导入*作为foo)类似于冻结对象的属性。

有关更多信息,请参见In ES6, imports are live read-only views on exported values

当我将import * as m from './module'更改为import m from './module';时,错误消失了。

打包版本:

"typescript": "^3.6.4"
"ts-jest": "^24.1.0"
"jest": "^24.9.0",

jest.config.js

module.exports = {
  preset: 'ts-jest/presets/js-with-ts',
  //...
}

tsconfig.json

"compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    //...
}