gle*_*hes 4 javascript unit-testing mocking jestjs
我正在编写一个Jest模拟,但是在模拟本身之外定义模拟函数时似乎有问题。
我有一堂课:
myClass.js    
class MyClass {
  constructor(name) {
    this.name = name;
  }
  methodOne(val) {
    return val + 1;
 }
  methodTwo() {
    return 2;
  }
}
export default MyClass;
和一个使用它的文件:
testSubject.js
import MyClass from './myClass';
const classInstance = new MyClass('Fido');
const testSubject = () => classInstance.methodOne(1) + classInstance.name;
export default testSubject;
测试:testSubject.test.js
import testSubject from './testSubject';
const mockFunction = jest.fn(() => 2)
jest.mock('./myClass', () => () => ({
    name: 'Name',
    methodOne: mockFunction,
    methodTwo: jest.fn(),
}))
describe('MyClass tests', () => {
    it('test one', () => {
        const result = testSubject()
        expect(result).toEqual('2Name')
    })
})
但是,出现以下错误:
TypeError: classInstance.methodOne is not a function
如果我改写:
...
methodOne: jest.fn(() => 2)
然后测试通过就没问题了。
有没有一种方法可以在模拟本身之外进行定义?
谢谢!
我想通了。与提升有关,参见:Jest mocking 参考错误
它在我之前做过的测试中起作用的原因是因为 testSubject 本身就是一个类。这意味着当 testSubject 被实例化时,它是在测试文件中的变量声明之后,所以模拟可以使用它。
因此,在上述情况下,它永远不会起作用。
对于其他 Jest 新手,如果您像这样模拟同一个包或模块中的多个函数:
jest.mock(
  'pathToModule',
  () => ({
    functionA: jest.fn(() => {
      return 'contentA';
    }),
  })
);
jest.mock(
  'pathToModule',
  () => ({
    functionB: jest.fn(() => {
      return 'contentB';
    }),
  })
);
第二个模拟将覆盖第一个模拟,最终您将得到functionA不是一个函数。
如果它们都来自同一模块,只需将它们组合起来即可。
jest.mock(
  'samePathToModule',
  () => ({
    functionA: jest.fn(() => {
      return 'contentA';
    }),
    functionB: jest.fn(() => {
      return 'contentB';
    }),
  })
);
定义mockOne为未分配的变量let,然后在模拟函数内初始化该变量对我有用:
let mockFunction
jest.mock('./myClass', () => () => {
    mockFunction = jest.fn(() => 2)
    return {
        name: 'Name',
        methodOne: mockFunction,
        methodTwo: jest.fn(),
    }
}))
就我而言,我必须模拟一个节点模块。我在ES6中使用React和Redux,并在Jest和Enzyme中进行单元测试。
在我正在使用并为其编写测试的文件中,将默认导入节点模块:
import nodeModulePackate from 'nodeModulePackage';
因此,由于不断出现错误,我需要将其作为默认值进行模拟(0, _blah.default) is not a function.。我的解决方案是:
jest.mock('nodeModulePackage', () => jest.fn(() => {}));
就我而言,我只需要重写该函数并使它返回一个空对象。
如果您需要在该节点模块上调用函数,请执行以下操作:
jest.mock('nodeModulePackage', () => ({ doSomething: jest.fn(() => return 'foo') }));
希望这可以帮助某人:)