jest.mock中的Jest'TypeError:is not a function'

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;
Run Code Online (Sandbox Code Playgroud)

和一个使用它的文件:

testSubject.js

import MyClass from './myClass';

const classInstance = new MyClass('Fido');

const testSubject = () => classInstance.methodOne(1) + classInstance.name;

export default testSubject;
Run Code Online (Sandbox Code Playgroud)

测试: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')
    })
})
Run Code Online (Sandbox Code Playgroud)

但是,出现以下错误:

TypeError: classInstance.methodOne is not a function
Run Code Online (Sandbox Code Playgroud)

如果我改写:

...
methodOne: jest.fn(() => 2)
Run Code Online (Sandbox Code Playgroud)

然后测试通过就没问题了。

有没有一种方法可以在模拟本身之外进行定义?

谢谢!

gle*_*hes 8

我想通了。与提升有关,参见:Jest mocking 参考错误

它在我之前做过的测试中起作用的原因是因为 testSubject 本身就是一个类。这意味着当 testSubject 被实例化时,它是在测试文件中的变量声明之后,所以模拟可以使用它。

因此,在上述情况下,它永远不会起作用。


Pan*_*per 8

对于其他 Jest 新手,如果您像这样模拟同一个包或模块中的多个函数:

jest.mock(
  'pathToModule',
  () => ({
    functionA: jest.fn(() => {
      return 'contentA';
    }),
  })
);

jest.mock(
  'pathToModule',
  () => ({
    functionB: jest.fn(() => {
      return 'contentB';
    }),
  })
);

Run Code Online (Sandbox Code Playgroud)

第二个模拟将覆盖第一个模拟,最终您将得到functionA不是一个函数。

如果它们都来自同一模块,只需将它们组合起来即可。

jest.mock(
  'samePathToModule',
  () => ({
    functionA: jest.fn(() => {
      return 'contentA';
    }),
    functionB: jest.fn(() => {
      return 'contentB';
    }),
  })
);
Run Code Online (Sandbox Code Playgroud)


Axe*_*ect 6

定义mockOne为未分配的变量let,然后在模拟函数内初始化该变量对我有用:

let mockFunction

jest.mock('./myClass', () => () => {
    mockFunction = jest.fn(() => 2)
    return {
        name: 'Name',
        methodOne: mockFunction,
        methodTwo: jest.fn(),
    }
}))
Run Code Online (Sandbox Code Playgroud)


jen*_*nki 5

就我而言,我必须模拟一个节点模块。我在ES6中使用React和Redux,并在Jest和Enzyme中进行单元测试。

在我正在使用并为其编写测试的文件中,将默认导入节点模块:

import nodeModulePackate from 'nodeModulePackage';
Run Code Online (Sandbox Code Playgroud)

因此,由于不断出现错误,我需要将其作为默认值进行模拟(0, _blah.default) is not a function.。我的解决方案是:

jest.mock('nodeModulePackage', () => jest.fn(() => {}));
Run Code Online (Sandbox Code Playgroud)

就我而言,我只需要重写该函数并使它返回一个空对象。

如果您需要在该节点模块上调用函数,请执行以下操作:

jest.mock('nodeModulePackage', () => ({ doSomething: jest.fn(() => return 'foo') }));
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助某人:)