What's the best way to check that events were fired in a Truffle test?
3 Answers
I wrote the truffle-assertions
package just for this. It has an assertion to check that an event has been emitted. Essentially, it is similar to the older answer here, but it does not need to check a specific index of the logs, and it has the option add complex conditions in a straightforward way by passing a filter function.
npm install truffle-assertions
You can import it at the top of your test file:
const truffleAssert = require('truffle-assertions');
And use it inside your test:
truffleAssert.eventEmitted(result, 'TestEvent', (args) => {
return args[0] === 10n && args.secondParamName === args[2];
});
I wrote a blog post that goes over the functionality with a detailed use case for further reading: Checking events when testing Solidity smart contracts with Truffle
-
How to test indexed events?
AssertionError: Event filter for onWithdraw returned no results
– SenjuCommented Nov 9, 2018 at 19:38 -
Indexed events should work as well. If you submit an issue to the repository with some code snippets, I can take a look at it. github.com/rkalis/truffle-assertions/issues Commented Nov 10, 2018 at 11:51
On top of Rosco's and Nick's answers, it's also helpful to be aware of the --show-events flag for debugging. Use it like this:
truffle test --show-events
There are already some solutions out there, such as at How to listen for contract events in JavaScript tests?. Those questions and answers describe how to listen for events, while I believe a better strategy is to check for events at the end of every transaction. This can be reliably and easily done by simply inspecting the transaction receipt (at least in the latest versions of ethereum). One strategy:
assertEventOfType: function(response, eventName, index) {
assert.equal(response.logs[index].event, eventName, eventName + ' event should fire.');
}
Then you just need to pass in the transaction response, along with the event you're looking for and the index of the event in the logs. If you don't care what order the events are fired in, you can nix the index
param and just search the logs instead. You can also check for all the other properties of the event, e.g. a user address the event is associated with, if you defined that as a param of your event.