Estoy probando mi contrato a través de las bibliotecas chai y truffle-assertions desde un archivo JavaScript y estoy probando si los eventos devuelven los valores correctos. Tengo un evento llamado Mensaje. En mi función, el evento se llama dos veces consecutivas pero con una identificación y un mensaje diferentes. El problema que tengo es que me da un error cada vez que trato de probar ambos eventos a pesar de que lo verifiqué en remix y todo parece funcionar. Solo probar los eventos (truffleAssert.eventEmitted(result, 'Message');) funciona bien.
No puedo dar a los eventos dos nombres diferentes ya que crearía un lío para el desarrollo posterior de mis contratos y terminaría con una enorme cantidad de eventos.
¿Cómo puedo hacer que las pruebas funcionen? ¿Hay una solución a este error?
Similar al siguiente (aunque no puedo compartir mi código real):
event Message(address id, bytes16 message);
function messages() public {
emit Message(0x1fe..., 'Almost there);
emit Message(0x0, 'Congratulations');
}
Y mi archivo de prueba se parece bastante a esto:
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.');
})
})
El último mensaje de error que recibo es que espero que el evento devuelva la dirección 0x1fe... pero, en cambio, devuelve la dirección 0x0, por lo que parece que solo está viendo el regreso del último evento. Al mismo tiempo, incluso si ingreso la dirección 0x0 para ambos eventos, aún devuelve un mensaje de error.
¡Gracias!
Si bien la respuesta de Aquila puede funcionar como una solución alternativa, la forma en que truffleAssert.eventEmitted()
funciona es aplicando una función de filtro en los argumentos del evento. El inconveniente de esto es que no puede "afirmar" cada argumento individualmente, pero esto le permitirá ejecutar ambas afirmaciones de esta manera.
Vi en su otra pregunta que está usando Truffle v5 con Solidity v0.5.0, así que actualicé sus pruebas para usar Web3 v1.0.
Usé el siguiente código de solidez para probar:
event Message(address id, bytes16 message);
function messages() public {
emit Message(address(0), "Almost there");
emit Message(address(msg.sender), "Congratulations");
}
Y cambió las pruebas de Javascript a:
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.');
})
Ambas pruebas pasan con Truffle v5, Solidity v0.5.0, truffle-assertions v0.7.1.
La primera declaración de truffleAssert.eventEmitted
maneja todos los eventos, es por eso que tiene el problema.
Significa que necesita afirmar todos los eventos en uno solo truffleAssert.eventEmitted
o puede usar una solución alternativa como:
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.');
})
en caso de contrato:
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
o construir una afirmación de evento propia basada enresult
Para trufa 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