Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jest 'TypeError: is not a function' in jest.mock

I'm writing a Jest mock, but I seem to have a problem when defining a mocked function outside of the mock itself.

I have a class:

myClass.js

class MyClass {
  constructor(name) {
    this.name = name;
  }

  methodOne(val) {
    return val + 1;
  }

  methodTwo() {
    return 2;
  }
}

export default MyClass;

And a file using it:

testSubject.js

import MyClass from './myClass';

const classInstance = new MyClass('Fido');

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

export default testSubject;

And the test:

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

However, I get the following error:

TypeError: classInstance.methodOne is not a function

If I instead write:

...
methodOne: jest.fn(() => 2)

Then the test passes no problem.

Is there a way of defining this outside of the mock itself?

like image 945
glenrothes Avatar asked Aug 21 '18 23:08

glenrothes


People also ask

What is Jest mock function?

Mock functions allow you to test the links between code by erasing the actual implementation of a function, capturing calls to the function (and the parameters passed in those calls), capturing instances of constructor functions when instantiated with new , and allowing test-time configuration of return values.

How do you mock a particular function in Jest?

Function mock using jest. The simplest and most common way of creating a mock is jest. fn() method. If no implementation is provided, it will return the undefined value. There is plenty of helpful methods on returned Jest mock to control its input, output and implementation.

What is __ mocks __ in Jest?

Manual mocks are defined by writing a module in a __mocks__/ subdirectory immediately adjacent to the module. For example, to mock a module called user in the models directory, create a file called user. js and put it in the models/__mocks__ directory.

How do you mock a function in Jest react?

Let's refactor the test to use this approach: test("Should render character name", async () => { const mock = jest. spyOn(data, "getCharacter"). mockResolvedValue("Bob"); render(<Hello id={1} />); expect(await screen.


3 Answers

In my case, I had to mock a Node.js module. I'm using React and Redux in ES6, with Jest and Enzyme for unit tests.

In the file I'm using, and writing a test for, I'm importing the node modules as default:

import nodeModulePackage from 'nodeModulePackage';

So I needed to mock it as a default since I kept getting the error (0, _blah.default) is not a function..

My solution was to do:

jest.mock('nodeModulePackage', () => jest.fn(() => {}));

In my case, I just needed to override the function and make it return an empty object.

If you need to call a function on that node module, you'll do the following:

jest.mock('nodeModulePackage', () => ({ doSomething: jest.fn(() => 'foo') }));
like image 75
jenkizenki Avatar answered Oct 30 '22 23:10

jenkizenki


I figured this out. It is to do with hoisting, see: Jest mocking reference error

The reason it had worked in a previous test, where I had done it, was because the testSubject was itself a class. This meant that when the testSubject was instantiated, it was after the variable declaration in the test file, so the mock had access to use it.

So in the above case it was never going to work.

like image 23
glenrothes Avatar answered Oct 30 '22 23:10

glenrothes


Defining mockOne as an unassigned let and then initialising the variable inside the mocking function worked for me:

let mockFunction

jest.mock('./myClass', () => () => {
    mockFunction = jest.fn(() => 2)
    return {
        name: 'Name',
        methodOne: mockFunction,
        methodTwo: jest.fn(),
    }
}))
like image 4
AxeEffect Avatar answered Oct 30 '22 23:10

AxeEffect