Solidity

如何測試從函式內部呼叫另一個合約的函式?

  • March 7, 2022

新令牌.sol

import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol";

contract newToken is ERC1155 {
   using Counters for Counters.Counter;
   Counters.Counter private _nftIds;
   address owner;

   
   event minted (string uri);
   constructor(string memory _uri,address _owner)ERC1155(_uri){
       owner=_owner;  
   }
   modifier onlyOwner{
       require(msg.sender==owner);
       _;
   }
   function mint(uint _amount,string memory  _uri)public  returns(uint){
      _nftIds.increment();
      uint currentId=_nftIds.current();
      _mint(owner,currentId,_amount,"");
      _setURI(_uri);
      emit minted(_uri);
      return currentId;
   }
   function transfer(address _to,uint _id, uint _amount)public returns(bool success){
       safeTransferFrom(
        owner,
        _to,
        _id,
        _amount,
       ""
   ) ;
   return true;

   }
   

}


contract createContract {
   newToken[] contractAddress;
   mapping(address=>newToken) public contracts;

   function create(string memory _uri) public {
       newToken addr=new newToken(_uri,msg.sender);
       contractAddress.push(addr);
       contracts[msg.sender]=addr;
   }
   function mint(string memory _uri)public  returns(newToken)  {
       if (address(contracts[msg.sender])==address(0)){
           create(_uri);
           contracts[msg.sender].mint(1,_uri);
           return contracts[msg.sender];

       }
       else{
           contracts[msg.sender].mint(1,_uri);
           return contracts[msg.sender];
       }
       
   }

}

我想為 createContract 智能合約中的 create 函式編寫單元測試。

我的測試程式碼

const { assert } = require('chai');



// pass the name of the contract you want to test
const createContract = artifacts.require('createContract')

require('chai')
   .use(require('chai-as-promised'))
   .should()

contract('createContract', (accounts) => {
   let contract_Fandom 

   // accounts of ganache 
   console.log("accounts>>>>>",accounts)




   // console.log("HIIIIIIIIIIII")

   before  (async ()=> {
       console.log("Bye--------------")
       //abi of contracts  
       contract_createContract  = await createContract.deployed() // abi of contracts  
   
       // console.log('ABI....of contractNFT....',contract_Fandom)
   })

   describe('deployment of  newToken ', async() => {
       it('deploys successfully', async()=> {
           const address = contract_createContract.address
           console.log("createContract Contract Address -->> ",address)
           assert.notEqual(address,'')
           assert.notEqual(address,0x0)
           assert.notEqual(address,null)
           assert.notEqual(address,undefined)
           assert.ok(address)

       })
   
   })

   describe('Mint ', async() => {
       it('Mint function testing ', async()=>{

           const result_createContract = await contract_createContract.create('www.example.com',{from : accounts[0]})
           console.log("---->>>>",result_createContract)
          
       })
   })
})

我假設您的問題是“我如何與在 ‘createContract.create’ 中創建的已部署的 ’newToken’ 合約進行互動?”。我之前沒有使用過 truffle,所以下面的程式碼是未經測試的。

為“newToken”合約添加工件。

const newToken = artifacts.require('newToken')

現在你需要以某種方式從合約中獲取新創建的地址。

...
   describe('Mint ', async() => {
       it('Mint function testing ', async()=>{

           await contract_createContract.create('www.example.com', {from : accounts[0]})
           // fetch the newly created address from the public mapping
           const newTokenAddress = await contract_createContract.contracts(accounts[0])
           const contract_newToken = await newToken.at(newTokenAddress)
           // run tests...

          
       })
   })

作為替代方案:檢索地址的一種更強大的方法可能是發出一個事件,因為這樣合約的創建和讀取就不會分離。

...
   event ContractCreated(address newTokenAddress);

   function create(string memory _uri) public {
       newToken addr=new newToken(_uri,msg.sender);
       contractAddress.push(addr);
       contracts[msg.sender]=addr;
       emit ContractCreated(address(newToken));
   }

並從日誌中過濾地址。

...
           const result = await contract_createContract.create('www.example.com', {from : accounts[0]})
           cont contract_newToken = await newToken.at(result.logs[0].args[0])

引用自:https://ethereum.stackexchange.com/questions/119041