1

newToken.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]; } } } 

I want to write unit testing for create function inside createContract smart contract.

my test code

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) }) }) }) 

2 Answers 2

2
+150

I'm assuming your question is "How do I interact with the deployed 'newToken' contract created in 'createContract.create'?". I haven't used truffle before, so the following code is untested.

Add in the artifact for the 'newToken' contract.

const newToken = artifacts.require('newToken') 

And now you need to somehow fetch the newly created address from the contract.

... 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... }) }) 

As an alternative: A more robust way of retrieving the address would be perhaps by emitting an event, because that way the contract creation and the read are not decoupled.

... 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)); } 

And filtering the address from the logs.

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

Welcome to the community!

First off, let's discuss what should unit tests do, as you mentioned you want to test this out.

A unit test should take part in functionality (eg. a function in this case) and test all the possible cases within it. If there is any interaction with another contract that should be tested, those are called integration tests. Let me give you a couple of examples based on the code you shared with us:

Unit test, in this case, could be something like this:

const { assert } = require('chai'); contract('createContract', (accounts) => { describe('Mint ', async() => { it('Mint function testing', async() => { await createContract.create('www.example.com'); const createdContractAddress = await createContract.contractAddress(0); // Check if everything is set up properly in TESTING contract (createContract) assert.isEqual(await createContract.contracts(createdContractAddress), accounts[0]); }) }); 

This way, you are testing if everything within the contract that is being tested is set up as it should.

On the other hand, the integration test should look something like this:

const { assert } = require('chai'); contract('createContract', (accounts) => { describe('Mint ', async() => { const testUri = 'www.example.com'; it('Mint function testing', async() => { await createContract.create(testUri); const createdContactAddress = await createContract.contractAddress(0); const createdContract = await newContract.at(createdContactAddress); // Check if everything is set up properly in contract that interacts with current contract // (newContract), trough methods that are exposed assert.isEqual(await createdContract.uri(), testUri); assert.isEqual(await createdContract.owner(), accounts[0]); }) }); 

Both of these examples apply to the testing of any single contract or multiply connected ones. Most of the time, I find that in Solidity development, developers do the mix of both, which is great also and often good enough. The main advice is to test everything, try to cover possible edge cases, and most importantly, have in mind security guidelines for error-prone code.

2
  • In the test you are expecting that const result = await createContract.create(testUri,{from : accounts[0]}) will return the deployed contract address and that doesn't work because it is a transaction and the returned value is the receipt. Commented Mar 3, 2022 at 21:59
  • @Ismael Thank you for noticing this. I will update the comment so it won't be misleading anymore. Commented Mar 7, 2022 at 12:15

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.