Я тестирую свой контракт через библиотеки chai и truffle-assertions из файла JavaScript и проверяю, возвращают ли события правильные значения. У меня есть событие под названием Message. В моей функции событие вызывается дважды подряд, но с другим идентификатором и сообщением. У меня проблема в том, что она выдает ошибку всякий раз, когда я пытаюсь протестировать оба события, хотя я проверил это на ремиксе, и все, кажется, работает. Простое тестирование событий (truffleAssert.eventEmitted(result, 'Message');) работает нормально.
Я не могу давать событиям два разных имени, так как это создаст беспорядок для дальнейшей разработки моих контрактов, и в итоге я получу огромное количество событий.
Как заставить тесты работать? Есть ли обходной путь этой ошибки?
Подобно приведенному ниже (хотя я не могу поделиться своим фактическим кодом):
event Message(address id, bytes16 message);
function messages() public {
emit Message(0x1fe..., 'Almost there);
emit Message(0x0, 'Congratulations');
}
И мой тестовый файл выглядит примерно так:
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.');
})
})
Последнее сообщение об ошибке, которое я получаю, заключается в том, что я ожидаю, что событие вернет адрес 0x1fe..., но вместо этого оно возвращает адрес 0x0, поэтому похоже, что оно смотрит только на возвращение последнего события. В то же время, даже если я ввожу адрес 0x0 для обоих событий, он все равно возвращает сообщение об ошибке.
Спасибо!
Хотя ответ Aquila может работать как обходной путь, truffleAssert.eventEmitted()
он работает, применяя функцию фильтра к аргументам события. Недостатком этого является то, что вы не можете «утвердить» каждый аргумент по отдельности, но это позволит вам запускать оба утверждения таким образом.
Из вашего другого вопроса я понял, что вы используете Truffle v5 с Solidity v0.5.0, поэтому я обновил ваши тесты, чтобы использовать Web3 v1.0.
Я использовал следующий код прочности для тестирования:
event Message(address id, bytes16 message);
function messages() public {
emit Message(address(0), "Almost there");
emit Message(address(msg.sender), "Congratulations");
}
И изменил тесты Javascript на:
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.');
})
Оба этих теста проходят с Truffle v5, Solidity v0.5.0, truffle-assertions v0.7.1.
Первое объявление truffleAssert.eventEmitted
обрабатывает все события, поэтому у вас возникла проблема.
Это означает, что вам нужно утверждать все события в одном truffleAssert.eventEmitted
или вы можете использовать обходной путь, например:
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.');
})
в случае контракта:
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
или создать собственное утверждение события на основеresult
Для трюфеля 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
});
Эмуль
Роско Калис
Эмуль