Prueba de interacciones de contrato con Truffle

Tengo 2 contratos, Usuario y Registro, interactuando y quiero probar sus interacciones con Truffle. Actualmente mi(s) prueba(s) para Usuario son

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

Ahora quiero probar la interacción entre el contrato de usuario y un contrato de registro. Las partes relevantes de cada uno son

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

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

¿Cómo puedo escribir una prueba en la que se implementa el Registro para poder probar register(), getContractAddress()etc.?

Revisé los documentos pero no encontré ejemplos allí.

EDITAR: solo para complementar la respuesta que se dio

agregué esto

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

Funciona y más abajo tengo una prueba para establecer/obtener la dirección de registro que funciona bien (lo que significa que cuando llamo a un método en el contrato, la dirección ya está allí). El problema está en esta prueba.

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

regresa Error: VM Exception while processing transaction: invalid opcode_ Hay esta pregunta aquí , pero no entendí cómo hacer que funcione desde allí (aunque hice públicas las asignaciones en el Registro).

Respuestas (1)

Primero debe implementar el contrato de registro y luego el usuario.

Puede agregar un constructor al contrato de usuario para crear una instancia regcon la dirección del contrato de registro.

Además, al hacer su mapeo global public, el compilador de solidez creará automáticamente funciones getter, que serán necesarias para la prueba.

El constructor para Usuario se vería así:

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

En un archivo js para su prueba de trufas, puede comenzar escribiendo una cadena de promesas para cumplir con sus contratos. (Suponiendo que haya compilado y escrito migraciones para los contratos)

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)
})
De hecho, lo acepté demasiado rápido. Parcialmente funcionó para mí. El contrato se implementó y recuperé la dirección bien. Pero cuando trato de probar métodos que dependen de él, aparece el error Error: VM Exception while processing transaction: invalid opcode. He editado la pregunta para incluir eso.
@Sean Pollock!!! ¡¿¡¿qué onda amigo?!?!