I am working on writing tests for a project, and somewhere in the project there is a function containing the following code:
const erc20 = new Contract(
tokenAddress,
ERC20_ABI,
provider,
);
const approved = await erc20.allowance(walletAddress, ChainData.address);
I want to mock the erc20.allowance
function call so that the unittest I am writing for that function does not depend on this call, but I don't know how to do this.
I tried writing the following code:
jest.spyOn(Contract.prototype, 'allowance').mockImplementation(() => {
console.log('mocking success!');
return BigNumber.from('100000');
});
but I get an error when running it:
Property `allowance` does not exist in the provided object
I also tried using jest.mock
to mock the whole Contract class but it does not work:
describe('getAllowance', () => {
jest.mock('ethers', () => {
return jest.fn().mockImplementation(() => {
class MockContract {
async allowance() {
console.log('mocking success!');
return BigNumber.from('100000');
}
}
return {
...originalEthers,
Contract: MockContract,
};
});
});
it('should return the allowance if everything is alright', async () => {
expect.assertions(1);
const response = await approveService.getAllowance(
1116,
tokenAddress,
'some wallet address',
);
expect(response.allowance).toBe('100000');
});
});
I was finally able to mock another module using jest. The problem was that I needed to put jest.mock
in the global scope of the test file for it to work. This led to another problem of course: the mock would not be test case specific and would be there for all of test cases in a file. It is a much easier problem though and can be fixed by a couple of ways, like for example moving test cases to different files or writing more complex mock implementations that would cover the other test cases as well.