我正在为一个项目编写测试,项目中的某个地方有一个包含以下代码的函数:
const erc20 = new Contract(
tokenAddress,
ERC20_ABI,
provider,
);
const approved = await erc20.allowance(walletAddress, ChainData.address);
我想模拟
erc20.allowance
函数调用,以便我为该函数编写的单元测试不依赖于此调用,但我不知道该怎么做。
我尝试编写以下代码:
jest.spyOn(Contract.prototype, 'allowance').mockImplementation(() => {
console.log('mocking success!');
return BigNumber.from('100000');
});
但运行时出现错误:
Property `allowance` does not exist in the provided object
我还尝试使用
jest.mock
来模拟整个 Contract 类,但它不起作用:
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');
});
});
我终于能够使用 jest 来模拟另一个模块了。问题是我需要将
jest.mock
放在测试文件的全局范围内才能正常工作。这当然导致了另一个问题:模拟不会是特定于测试用例的,并且会存在于文件中的所有测试用例中。不过,这是一个更容易的问题,可以通过几种方法来解决,例如将测试用例移动到不同的文件或编写更复杂的模拟实现来覆盖其他测试用例。