Ich habe 2 Verträge, Benutzer und Registrierung, die interagieren, und ich möchte ihre Interaktionen mit Truffle testen. Aktuell sind meine Test(s) für User
contract('User', function(accounts) {
// many tests here which only depend on User contract
})
Ich möchte nun das Zusammenspiel zwischen dem Nutzungsvertrag und einem Registry-Vertrag testen. Die relevanten Teile von jedem sind
Benutzer.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();
}
}
Wie kann ich einen Test schreiben, in dem die Registrierung bereitgestellt wird, damit ich dann register()
, getContractAddress()
, usw. testen kann?
Ich habe mir die Dokumentation angesehen , aber dort keine Beispiele gefunden.
BEARBEITEN: Nur zur Ergänzung der gegebenen Antwort
Ich habe dies hinzugefügt
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
})
Es funktioniert und weiter unten habe ich einen Test zum Festlegen / Abrufen der Registrierungsadresse, der einwandfrei funktioniert (was bedeutet, dass die Adresse bereits vorhanden ist, wenn ich eine Methode im Vertrag aufrufe). Das Problem liegt in diesem 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()
})
})
es kehrt zurück Error: VM Exception while processing transaction: invalid opcode
. Es gibt diese Frage hier , aber ich habe nicht verstanden, wie sie von dort aus funktioniert (obwohl ich die Zuordnungen in der Registrierung öffentlich gemacht habe).
Sie sollten zuerst den Registrierungsvertrag und dann den Benutzer bereitstellen.
Sie können dem Benutzervertrag einen Konstruktor hinzufügen, um ihn reg
mit der Adresse des Registrierungsvertrags zu instanziieren.
Wenn Sie Ihr Mapping globals machen public
, erstellt der Solidity-Compiler automatisch Getter-Funktionen, die zum Testen erforderlich sind.
Der Konstruktor für User würde so aussehen:
function User(address _registry) {
reg = _registry;
}
In einer js-Datei für Ihren Trüffeltest können Sie beginnen, indem Sie eine Versprechenskette schreiben, um Ihre Verträge zu erfüllen. (Vorausgesetzt, Sie haben Migrationen für die Verträge zusammengestellt und geschrieben)
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)
})
mcansado
Error: VM Exception while processing transaction: invalid opcode
. Ich habe die Frage so bearbeitet, dass sie das enthält.smatthewenglisch