0

The test:

import Web3 from 'web3';

jest.mock('web3', ()=>{
    return jest.fn().mockImplementation(()=>'Hello, world!')
});

describe('app', ()=>{
    test('mock web3', ()=>{
        console.log('web3:', Web3);
        let web3 = new Web3(window.ethereum);
        console.log("new web3:", web3);
    });
});

package.json:

{
    "name": "test",
    "dependencies": {
        "react-scripts": "5.0.1",
        "web3": "^1.7.5"
    },
    "devDependencies":{
    },
    "scripts": {
        "test": "react-scripts test"
    }
}

Invoke with npm i && npm test;. The first console.log shows that I have mocked the module. The second console.log shows that something went wrong. The output of the second log statement is

new web3: mockConstructor {}

but I expect something like

new web3: "Hello, world!"

I've tried many permutations including moving the import below jest.mock and changing the import to const Web3 = require('web3');. If I remove the require or import, the test fails with "ReferenceError: Web3 is not defined" as expected.

I've reviewed other questions including Jest : mock constructor function, Jest mock a constructor, and Mock a dependency's constructor Jest, which suggest that this method should work. One salient difference is that I'm mocking a default import's constructor rather than a named import.

How do I mock the Web3 constructor to return a mocked object?

lmat - Reinstate Monica
  • 7,289
  • 6
  • 48
  • 62

1 Answers1

0

For some reason, you can't use a jest.fn like that. It seems that you could, and lots of documentation suggests you can, so it's probably a bug. As a workaround, use a regular function:

jest.mock('web3', ()=>{
    return function notJestFn() {return 'Hello, world!';}
});
lmat - Reinstate Monica
  • 7,289
  • 6
  • 48
  • 62