web-dev-qa-db-ja.com

トリュフでイーサリアムイベントログをテストする

呼び出しごとにイベントを発行するコントラクトの機能があります。

合格した各テストでイベントを発行したいのですが、いくつかのテストがあります。

it("should emit Error event when sending 5 ether", function(done){
  var insurance = CarInsurance.deployed();

  insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(done).catch(done);
});

it("should emit Error event when sending 5 ether", function(done){
  var insurance = CarInsurance.deployed();

  insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(function(txHash){
    assert.notEqual(txHash, null);
  }).then(done).catch(done);
});

it("should emit Error event when sending 5 ether", function(done){
  var insurance = CarInsurance.deployed();

  insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(function(done){
    done();
  }).catch(done);
});

結果は次のとおりです。

1) should emit Error event when sending 5 ether

Events emitted during test:
---------------------------

Error(error: Must send 10 ether)

---------------------------
✓ should emit Error event when sending 5 ether (11120ms)
✓ should emit Error event when sending 5 ether (16077ms)


3 passing (51s)
1 failing

1) Contract: CarInsurance should emit Error event when sending 5 ether:
 Error: done() invoked with non-Error: 0x87ae32b8d9f8f09dbb5d7b36267370f19d2bda90d3cf7608629cd5ec17658e9b

ログに記録されたものだけが失敗することがわかります。

何か案が ?

ありがとうございました

11
ltheron

Txハッシュをdone()関数に渡しています。私は問題が一列に並んでいると思います:

insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(done).catch(done);

次のように変更します。

insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then(function() { done(); }).catch(done);

イベントをテストするには:

it("should check events", function(done) {
  var watcher = contract.Reward();

  // we'll send rewards
  contract.sendReward(1, 10000, {from: accounts[0]}).then(function() {
    return watcher.get();
  }).then(function(events) {
    // now we'll check that the events are correct
    assert.equal(events.length, 1);
    assert.equal(events[0].args.beneficiary.valueOf(), 1);
    assert.equal(events[0].args.value.valueOf(), 10000);
  }).then(done).catch(done);
});
12
Aldekein

Truffle v3以降、コールバック結果にログが記録されます。したがって、次のようなことができます。

insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')}).then((result) => { assert.equal(result.logs[0].event, "Error", "Expected Error event") })

https://github.com/trufflesuite/truffle-contract#processing-transaction-results を参照してください

6
satolizard

これを行うためのヘルパーがあります:

npm install --save truffle-test-utils

テストの上部:

require('truffle-test-utils').init();

あなたのテストでは:

let result = await insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')});
assert.web3Event(result, {
  event: 'Error',
  args: {
    error: 'Must send 10 ether'
  }
}, 'Error event when sending 5 ether');

完全な開示:私はこのパッケージの作者です。 SOでそのような解決策を探して書いたのですが、見つかりませんでした。

5
philippe_b

独自に作成する代わりに、Truffleのテストユーティリティを使用することもできます expectEvent.js

const { inLogs } = require('openzeppelin-solidity/test/helpers/expectEvent')
require('chai').use(require('chai-bignumber')(BigNumber)).should()
...
{ logs: this.logs } = await this.token.burn(amount, { from: owner })
...
const event = inLogs(this.logs, 'Burn')
event.args.burner.should.eq(owner)
event.args.value.should.be.bignumber.equal(amount)

例はTruffleの BurnableToken.behavior.js にあります。

2
Richard Fu

イベントが発行されたことを確認するためのアサーションを持つtruffle-assertionsパッケージを使用できます。また、イベント引数に複雑な条件をチェックするためにフィルター関数を渡すオプションもあります。

npm install truffle-assertions

テストファイルの先頭にインポートできます。

const truffleAssert = require('truffle-assertions');

そして、テスト内で使用します。

let txResult = await insurance.send({from: accounts[0], value: web3.toWei(5, 'ether')});
truffleAssert.eventEmitted(txResult, 'Error', (ev) => {
    return ev.error === 'Must send 10 ether';
}

免責事項:私は自分のテストで使用するためにこのパッケージを作成しました。フィルター関数を追加することで、非常に簡単な方法でイベント引数に複雑な条件をチェックすることができます。私はブログに これをより詳細に説明する記事 を書きました。

0
Rosco Kalis

特にasync/awaitを使用したい場合は、これを支援するためにいくつかの参照を追跡することができました。

it('can create a unique star and get its name', async function () {
        const event = this.contract.starClaimed({});
        event.watch(async (err, result) => {
           if (err) console.log("Somethings wrong...");

           if (result.args.owner === accounts[0]) {
               let token = result.args._token;
               event.stopWatching;

               const star = await this.contract.tokenIdToStarInfo(token);

               assert.equal(star[0], 'awesome star!');
               assert.equal(star[1], 'yada yada yada');
               assert.equal(star[2], 'dec_test');
               assert.equal(star[3], 'mag_test');
               assert.equal(star[4], 'cent_test');
           }
        });

        await this.contract.createStar('awesome star!', 'yada yada yada', 'dec_test', 'mag_test', 'cent_test', {from: accounts[0]});
    });

私が見つけたリファレンスは次のとおりです: https://github.com/trufflesuite/truffle-contract/issues/117

0
James Grunewald