0

I have a hub contract (1) that uses a contract factory (2) to create a contract (3). I am writing some tests in JavaScript to ensure that contract 3 is created correctly. I can tell events are being emitted correctly, but when I want to check the functions of contract 3 (#tryingtobethorough), it looks like Truffle does not recognize the created contract 3 address as a contract (i.e. TypeError: contract3Address.functionName is not a function). Does Truffle Javascript testing only recognize addresses as contracts if deployed through Truffle migrations? Is there a work around for this in Javascript? Perhaps it is a better test case for Solidity testing?

Below is some simplified versions of what I am working with:

Contract 1: Hub

import "./Contract2Interface.sol"; 

contract Contract1 {
    Contract2Interface I; 
    function Contract1(address Contract2Address){
        I = Contract2Interface(Contract2Address); 
    }
    function creation() returns (address newcontract3) {
        address theCreatedContract3 = I.createNewContract3();
        return newcontract3; 
    }
}

Contract 2: Contract Factory

import "./Contract3.sol";
import "./Contract2Interface.sol";

contract Contract2 is Contract2Interface {
    event ContractCreation(address _newContract);

    function createNewContract3() public returns(address) {

        Contract3 createdContract3 = new Contract3(); 
        ContractCreation(createdContract3);
        return createdContract3; 

    }
}

Contract 3: Contract to be Created

contract Contract3{
    uint256 public num; 
    function storeNum(uint256 newNum) public returns(bool) {
        num = newNum; 
    }
}

JavaScript Test This is simplified, but I think it gives enough of an idea.

beforeEach(async function(){
    contractFactory = await Contract2.new(); 
    contractHub = await Contract1.new(contractFactory.address);
  });

describe("Creating contract 3", async function(){
    it("Should allow us to create contract 3", async function(){
      let result = await contract1.createNewContract3({from: owner});
      //Event data 
      let log = resultTwo.logs[0];
      let contract3Address = log.args._newContract;
      console.log(contract3Address) //I can see this is a valid contract address & event has been emitted properly.
      let newnum = await contract3Address.storeNum(7);
      // At this point I get an error that "storeNum" is not a function of contract3Address from Truffle testing
    })
  })
2

A couple of issues

In the function creation of Contract1 you are returning newcontract3 without it being assigned a value, since it is an addres the returned value will be default address(0x0). You probably want to assign the result of createNewContract3().

function creation() returns (address newcontract3) {
    newcontract3 = I.createNewContract3();
    return newcontract3; 
}

In your test you assign to contract3Address the parameter of the event which is of type string. In truffle when you want to interact with a contract at a given address you need to get an instance pointing to that address, ie const myContract = await MyContract.at("address");.

describe("Creating contract 3", async function(){
    it("Should allow us to create contract 3", async function(){
      let result = await contract1.createNewContract3({from: owner});
      //Event data 
      let log = resultTwo.logs[0];
      let contract3Address = log.args._newContract;

      // Get instance pointing to address obtained from event
      const contract3 = await Contract3.at(contract3Address);

      let newnum = await contract3.storeNum(7);
      // At this point I get an error that "storeNum" is not a function of contract3Address from Truffle testing
    })
  })
  • Thank you! The former mistake is a typo by me when trying to shorten this down to post, but the latter solution is exactly what I needed to be reminded of, thanks! – Karen S Mar 14 '18 at 15:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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