0

My function that I want to test in the following:

getData: async function(){
  if(typeof window.ethereum !== 'undefined') {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const contract = new ethers.Contract(this.contractAddress, NftContract.abi, provider); //new instance of the contract to interact with the function of the contract
    try {
      const cost = await contract.cost();
      const totalSupply = await contract.totalSupply();
      this.data.cost = String(cost);
      this.data.totalSupply = String(totalSupply);
    }
    catch(err) {
      this.setError('An error occured to get the data');
    }
  }
}

My test is the following:

it('getData function should affect the cost and totalSupply to the data', async () => {
    const wrapper = shallowMount(NFTMintComponent);
    await wrapper.setData({
      contractAddress: '0x10Bc587867D87d1Ea1Cd62eac01b6DD027c182E9',
      ownerAddress: '0xe14d2f7105f759a100eab6559282083e0d5760ff',
      userAddress: '',
      data: {
        cost: '',
        totalSupply: ''
      },
      error: '',
      success: ''
    });

window.ethereum = jest.fn();//= [];
const window_ethereum = 'window_ethereum';
window.ethereum.mockResolvedValue(window_ethereum);
const ethers = {
    providers: {
        Web3Provider: jest.fn()
    },
    Contract: jest.fn()
}

const provider = 'provider';
ethers.providers.Web3Provider.mockResolvedValue(provider);

const contractMocked = 'contract';
ethers.Contract.mockResolvedValue(contractMocked);

const contract = {
    cost: jest.fn(),
    totalSupply: jest.fn()
};

const costMocked = 5;
const totalSupplyMocked = 50;
contract.cost.mockResolvedValue(costMocked);
contract.totalSupply.mockResolvedValue(totalSupplyMocked);

await wrapper.vm.getData();

  });

I expect that result:

expect(wrapper.vm.data.cost).toBe('5');

expect(wrapper.vm.data.totalSupply).toBe('50');

The test returns me '' instead of the values I mocked. Why do wrapper.vm.data.cost is '' instead of '5' ? same with wrapper.vm.data.totalSupply ?

UPDATE My test:

  let wrapper;

  beforeEach(() => {
    // use this to check the state of anything in the view
    wrapper = shallowMount(NFTMintComponent);
  });
it('getData function should affect the cost and totalSupply to the data', async () => {

    //window.ethereum = jest.fn();
    //const window_ethereum = 'window_ethereum_test';
    //window.ethereum.mockResolvedValue(window_ethereum);
    window.ethereum = [];
    window.ethereum.request = jest.fn();
    const accounts = ['0xe14d2f7105f759a100eab6559282083e0d5760ff'];
    window.ethereum.request.mockResolvedValue(accounts);

    let ethers = {
        providers: {
            Web3Provider: jest.fn()
        },
        Contract: jest.fn()
    }

    const provider = 'ropsten';
    ethers.providers.Web3Provider.mockResolvedValue(provider);

    const contractMocked = 'contract';
    ethers.Contract.mockResolvedValue(contractMocked);

    let contract = {
        cost: jest.fn(),
        totalSupply: jest.fn()
    };

    const costMocked = 5;
    const totalSupplyMocked = 50;
    contract.cost.mockResolvedValue(costMocked);
    contract.totalSupply.mockResolvedValue(totalSupplyMocked);

    await wrapper.vm.getData();
    //console.log(wrapper.vm.data);

    expect(wrapper.vm.data.cost).toBe('5');
    expect(wrapper.vm.data.totalSupply).toBe('50');
  });

My test enter into the 'try' but stops at const cost = await contract.cost(); with the following error: Could not detect network ... event: 'invalidNetwork' reason 'invalid BigNumber value'

I think I don't mocked well my ethers.providers.Web3Provider or my ethers.Contract.

How to mock the provider and the contract ?

3
  • The cost and totalSupply are empty strings in your call to setData. If you update these initial values, will it still return empty strings or these new values instead? This might give you a better idea of where your code is going wrong. Commented Oct 7, 2022 at 13:36
  • Also, the getData method creates a new instance of contract w/in itself. So the values in your contract variable w/in the test will be ignored when creating the new instance in getData. If this is a common object in your tests then you may want to move it to a beforeAll/each and then remove the "const" when redefining Commented Oct 7, 2022 at 13:39
  • I initialize my cost and totalsupply to '' but after my test of getData(), these values should be '5' and '50'. I edited my post because I think the problem it's the way I mocked my provider and my contract. My test goes into the try loop but catch an error instead of doing await contract.cost();
    – DamTan
    Commented Oct 8, 2022 at 8:52

1 Answer 1

0

I found a solution: I'm using eth-testing package to mock the provider and contract interaction:

  it('getData function should affect the cost and totalSupply to the data', async () => {

    // Start with not connected wallet
    testingUtils.mockNotConnectedWallet();
    // Mock the connection request of MetaMask
    testingUtils.mockRequestAccounts(["0xe14d2f7105f759a100eab6559282083e0d5760ff"]);
    //allows to mock the chain ID / network to which the provider is connected --> 0x3 Ropsten network
    testingUtils.mockChainId("0x3");

    const abi = NftContract.abi;
    // An address may be optionally given as second argument, advised in case of multiple similar contracts
    const contractTestingUtils = testingUtils.generateContractUtils(abi);

    await contractTestingUtils.mockCall("cost", [5]);
    await contractTestingUtils.mockCall("totalSupply", [50]);

    await wrapper.vm.getData();

    expect(wrapper.vm.data.cost).toBe('5');
    expect(wrapper.vm.data.totalSupply).toBe('50');
  });

If someone has another solution, please let us know

1
  • It works but I have an issue when mocking transactions using ethers. ``` TypeError: checkProvider(...).getTransactionCount is not a function``` Commented Feb 9 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.