0

I have 2 contracts, User and Registry, interacting and I want to test their interactions with Truffle. Currently my test(s) for User are

contract('User', function(accounts) {
  // many tests here which only depend on User contract
})

I now want to test the interaction between the user contract and a registry contract. The relevant parts of each are

User.sol

pragma solidity ^0.4.11;

import "./Registry.sol";

contract User { 
    address owner;
    address reg;
    bool verified;
    Registry registry = Registry(reg);

    // Register in the system
    function register(bytes32 _id)
        onlyOwner
    {
        registry.register(_id);
    }
    function getContractAddress(bytes32 _id)
        onlyOwner
    {
        registry.getContractAddress(_id);
    }
    function getPublicAddress(bytes32 _id)
        onlyOwner
    {
        registry.getPublicAddress(_id);
    }
    function verify()
        onlyReg
    {
        verified = true;
    }
}

Registry.sol

pragma solidity ^0.4.11;

import "./User.sol";

contract Registry {
    mapping(bytes32 => address) ID;
    mapping(address => address) Contract;

    function register(bytes32 _id) {
        ID[_id] = tx.origin;
        Contract[tx.origin] = msg.sender;
    }

    function getPublicAddress(bytes32 _id) constant returns (address) {
        return (ID[_id]);
    }

    function getContractAddress(bytes32 _id) constant returns (address) { 
        return Contract[ID[_id]];
    }   

    function verify() {
        User requester = User(msg.sender);
        requester.verify();
    }
}

How can I write a test in which Registry is deployed so I can then test register(), getContractAddress(), etc?

I checked out the docs but didn't find examples there.

EDIT: Just to complement to answer that was given

I added this

contract('User', function(accounts) {
  var user 
  var registry // new part based on your answer
  Registry.new().then((inst) => {
    registry = inst;
  })

  // Check contract was deployed
  it("Should retrieve deployed contract", function(done) {
      // test
  })

It works and further down I have a test to set/get reg address which works fine (which means by the time I call a method on the contract, the address is already there). The problem is in this test

// Should not find user
  it("Should not find user", function(done) {
    patient.getPublicAddress(web3.fromAscii("123456789"), {from:accounts[0], to:patient.address})
    .then(function(res) {
      assert.equal(res, 0);
      done()
    }, function(error) {
        // Force an error if callback fails.
        console.error(error)
        assert.equal(true, false)
        done()
      })
  })

it returns Error: VM Exception while processing transaction: invalid opcode. There is this question here but I didn't get how to make it work from there (though I did make the mappings public in Registry).

1

You should first deploy Registry contract and then User.

You can add a constructor to the User contract to instantiate reg with the address of the Registry contract.

Also by making your mapping globals public, the solidity compiler will automatically create getter functions, which will be necessary for testing.

The constructor for User would look like this:

function User(address _registry) {
    reg = _registry;
} 

In a js file for your truffle test, you can get started by writing a promise chain to hit your contracts. (Assuming you have compiled and written migrations for the contracts)

const Registry = artifacts.require('./Registry.sol')
const User = artifacts.require('./User.sol')

let registry
let user
let id = '0x...' // bytes 32 id

Registry.new().then((inst) => {
    registry = inst
    return User.new(registry.address)
}).then((inst) => {
    user = inst
    return user.register.call(id)
}).then((res) => {
    return registry.ID.call(id)
}).then((res) => {
    assert.equal(user.address, res)
})
  • I actually accepted it too fast. It partially worked for me. The contract was deployed and I got back the address fine. But when I try to test methods which depend on it I get the error Error: VM Exception while processing transaction: invalid opcode. I've edited the question to include that. – mcansado Aug 22 '17 at 16:34

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.