Ich teste meinen Vertrag über die Bibliotheken chai und truffle-assertions aus einer JavaScript-Datei und teste, ob Ereignisse die richtigen Werte zurückgeben. Ich habe ein Ereignis namens Nachricht. In meiner Funktion wird das Ereignis zweimal hintereinander aufgerufen, jedoch mit einer anderen ID und Nachricht. Das Problem, das ich habe, ist, dass es mir einen Fehler gibt, wenn ich versuche, auf beide Ereignisse zu testen, obwohl ich es auf Remix überprüft habe und alles zu funktionieren scheint. Nur das Testen der Ereignisse (truffleAssert.eventEmitted(result, 'Message');) funktioniert einwandfrei.
Ich kann den Ereignissen nicht zwei verschiedene Namen geben, da dies die spätere Entwicklung meiner Verträge durcheinander bringen würde und ich am Ende eine enorme Menge an Ereignissen haben würde.
Wie kann ich die Tests zum Laufen bringen? Gibt es eine Problemumgehung für diesen Fehler?
Ähnlich wie unten (kann meinen tatsächlichen Code jedoch nicht teilen):
event Message(address id, bytes16 message);
function messages() public {
emit Message(0x1fe..., 'Almost there);
emit Message(0x0, 'Congratulations');
}
Und meine Testdatei sieht ungefähr so aus:
const Contract = artifacts.require('./Contract.sol')
const assert = require("chai").assert;
const truffleAssert = require('truffle-assertions');
contract('Contract', function(accounts) {
let contractInst;
let owner = accounts[0];
let user1 = accounts[1];
let user2 = accounts[2];
before('getting instance before all Test Cases', async function(){
contractInst = await Contract.new({from: owner});
})
it("should check that the correct events are returned", async () => {
let result = await contractInst.messages();
truffleAssert.eventEmitted(result, 'Message', (ev) => {
assert.equal(ev.id, user1, 'Correct id was returned');
assert.equal(web3.toUtf8(ev.message), "Almost there", 'Correct message was returned.');
return true;
}, 'Contract should return the correct message.');
truffleAssert.eventEmitted(result, 'Message', (ev) => {
assert.equal(ev.id, user2, 'Correct id was returned');
assert.equal(web3.toUtf8(ev.message), "Congratulations", 'Correct message was returned.');
return true;
}, 'Contract should return the correct message.');
})
})
Die letzte Fehlermeldung, die ich erhalte, ist, dass ich erwarte, dass das Ereignis die Adresse 0x1fe ... zurückgibt, aber stattdessen die Adresse 0x0 zurückgibt, sodass es so aussieht, als würde es nur die Rückgabe des letzten Ereignisses betrachten. Gleichzeitig gibt es immer noch eine Fehlermeldung zurück, selbst wenn ich die 0x0-Adresse für beide Ereignisse eingebe.
Danke!
Während die Antwort von Aquila als Problemumgehung funktionieren kann, truffleAssert.eventEmitted()
funktioniert dies, indem eine Filterfunktion auf die Argumente des Ereignisses angewendet wird. Der Nachteil dabei ist, dass Sie nicht jedes Argument einzeln "behaupten" können, aber dies ermöglicht es Ihnen, beide Behauptungen auf diese Weise auszuführen.
Ich habe aus Ihrer anderen Frage gesehen, dass Sie Truffle v5 mit Solidity v0.5.0 verwenden, also habe ich Ihre Tests aktualisiert, um Web3 v1.0 zu verwenden.
Ich habe den folgenden Solidity-Code zum Testen verwendet:
event Message(address id, bytes16 message);
function messages() public {
emit Message(address(0), "Almost there");
emit Message(address(msg.sender), "Congratulations");
}
Und die Javascript-Tests geändert in:
it("should check that the correct events are returned", async () => {
let result = await casino.messages();
truffleAssert.eventEmitted(result, 'Message', (ev) => {
return ev.id === '0x0000000000000000000000000000000000000000' && web3.utils.hexToUtf8(ev.message) === 'Almost there';
}, 'Contract should return the correct message.');
truffleAssert.eventEmitted(result, 'Message', (ev) => {
return ev.id === accounts[0] && web3.utils.hexToUtf8(ev.message) === 'Congratulations';
}, 'Contract should return the correct message.');
})
Beide Tests bestehen mit Truffle v5, Solidity v0.5.0, truffle-assertions v0.7.1.
Die erste Deklaration von truffleAssert.eventEmitted
behandelt alle Ereignisse, deshalb haben Sie das Problem.
Dies bedeutet, dass Sie alle Ereignisse einzeln geltend machen müssen, truffleAssert.eventEmitted
oder Sie können eine Problemumgehung wie folgt verwenden:
it("should check that the correct events are returned", async () => {
let result = await contractInst.messages({from: user1});
truffleAssert.eventEmitted(result, 'Message', (ev) => {
if(ev.id !== user1) return; // <- exit in case of second event
assert.equal(ev.id, user1, 'Correct id was returned');
assert.equal(web3.toUtf8(ev.message), "Almost there", 'Correct message was returned.');
return true;
}, 'Contract should return the correct message.');
truffleAssert.eventEmitted(result, 'Message', (ev) => {
if(ev.id === user1) return; // <- exit in case of first event
assert.equal(ev.id, '0x0000000000000000000000000000000000000000', 'Correct id was returned');
assert.equal(web3.toUtf8(ev.message), "Congratulations", 'Correct message was returned.');
return true;
}, 'Contract should return the correct message.');
})
im Vertragsfall:
pragma solidity ^0.4.21;
contract Ev {
event Message(address id, bytes16 message);
function messages() public {
emit Message(msg.sender, 'Almost there');
emit Message(0x0, 'Congratulations');
}
}
eventEmitted
oder erstelle eine eigene Event-Assertion basierend aufresult
Für Trüffel v5
it("...",async ()=>{
const result = await contractInst.messages({from: user1});
const events = await contractInst.getPastEvents('Message');
// iterate over the events
// and do the necessary assertions
});
Emul
Rosco Kalis
Emul