Truffle – How to Listen for Contract Events in JavaScript Tests

eventsjavascripttruffle

I'm trying to trigger events in my solidity contract to output some debug information in my javascript tests. However the events seem to get never caught.

That's the relevant contract code:

pragma solidity ^0.4.4;

contract CrowdFunding {

    uint public deadline;
    event DeadlineSet(uint deadline, uint timeNow);

    function withdrawal() returns(bool) {
        DeadlineSet(deadline, now);
        return true;
    }
}

Here's how I try to listen for the events in my JavaScript test file:

 var deadlineSet;
 deadlineSet = contractInstance.DeadlineSet({_from:web3.eth.coinbase});
 deadlineSet.watch(function(err, result) {
    if(err) {
        console.log(err);
        return;
    }
    console.log("Deadline " + result.args.deadline);
    console.log("Time Now " + result.args.timeNow);
    deadlineSet.stopWatching();
});

My tests are working fine and I can send money to the contract and call methods, but I never see any of the console outputs defined above.

Any help is appreciated.

Best Answer

I've discovered that not all events are displayed in the truffle output window, although they might have fired correctly with the execution of a contract. I believe this to still be an issue

After spending hours on this today I have come up with a solution to test that specific events are fired.

Here's my example truffle javascript test:

it("should do something that fires SaleMade", function() {
    return myContract
        .stockShelf("beer", "wine", {from: sellerAccount})
        .then(() => myContract.sell("water", "bread", {from: sellerAccount}))
        .then(() => utils.assertEvent(myContract, { event: "SaleMade", logIndex: 1, args: { name: "bread" }}));
}

The above filters the fired events that match the filter object passed to the assertEvent utility function I have in utils.js in the same folder. At the top of my javascript test I have declared:

var utils = require("./utils.js");

A snippet of my utils.js class is as follows:

var _ = require("lodash");
var Promise = require("bluebird");

module.exports = {
    assertEvent: function(contract, filter) {
        return new Promise((resolve, reject) => {
            var event = contract[filter.event]();
            event.watch();
            event.get((error, logs) => {
                var log = _.filter(logs, filter);
                if (log) {
                    resolve(log);
                } else {
                    throw Error("Failed to find filtered event for " + filter.event);
                }
            });
            event.stopWatching();
        });
    }
}

This requires other npm packages that aren't included with truffle by default. By default truffle doesn't include npm packages. I setup npm and installed the required packages like this:

npm init
npm install bluebird --save
npm install lodash --save

EDIT: Using testrpc

Related Topic