Как провести модульное тестирование, когда функция зависит от жестко запрограммированного развернутого адреса контракта?

Я писал модульные тесты для контракта, используя Hardhat + Ethers + Typescript, назовем его ContractA. Этот ContractA имеет жестко закодированный адрес развернутого токена ERC20, как здесь TokenA = '0x...'. Итак, в тестах я делаю:

ContractA = await ethers.getContractFactory("ContractA");
contractA = await upgrades.deployProxy(ContractA);

а затем приступаю к тестированию некоторых функций, которые работают нормально.

Но когда я пытаюсь протестировать определенную функцию в ContractA, которая использует жестко заданный адрес ERC20, например:

function buyExtra(address Owner, uint256 count) public whenNotPaused {
...
IERC20Upgradeable(TokenA).safeTransferFrom(msg.sender, address(this), count);
...
}

это не работает, и я получил сообщение об ошибкеError: VM Exception while processing transaction: revert Address: call to non-contract.

PS: я думаю, что понимаю причину, потому что адрес, указанный в ContractA, является адресом токена ERC20 в Rinkeby. Как такового в тестовой среде его нет.

И что же мне делать? Можно ли развернуть контракт ERC20 в тестовой среде с точно таким же адресом, что и в Ринкебю? Это то, что мне нужно сделать? Кстати, у меня нет контракта ERC20 в моем проекте.

Ответы (1)

Вы должны передавать информацию о развертывании в контракт, например, через конструктор. Тогда у вас есть некоторая гибкость в миграциях и тестах.

  • Если rinkeby, адрес = жестко заданный
  • В противном случае разверните заглушку и используйте этот адрес.

(Например).

Альтернативный способ — попытаться разветвить общедоступную цепочку, а затем протестировать ее.

Надеюсь, поможет

ОБНОВЛЯТЬ

import "./IERC20.sol";

contract X {

  IERC20 token;

  constructor(address _token) {
     token = IERC20(_token);
  }
}

Срисовал на телефоне. Без гарантии ;-)

большое спасибо! Я изменю свои контракты, чтобы передать адрес токена в конструкторе. После этого в тестах как он будет работать? Мне нужно только развернуть фиктивный контракт ERC20 и передать его адрес?
Звучит правильно. ЗатемIERC20 token = IERC20(thatAddress);