Testen einer Funktion, die eine nicht konstante Funktion aufruft

Ich habe eine nicht konstante Funktion in einem Vertrag:

contract InnerContract {
    event Event(uint256);

    function func(uint256 val) external returns (uint256) {
        Event(val);
        return val;
    }
}

Es wird von einer Funktion innerhalb eines anderen Vertrags aufgerufen:

import './InnerContract.sol';

contract OuterContract {
    InnerContract pInnerContract;

    function func(uint256 val) external returns (uint256) {
        return pInnerContract.func(val) + 1;
    }
}

Ich versuche, es in Trüffel über das folgende Skript zu testen:

contract('Test', () => {
    let hInnerContract;
    let hOuterContract;

    before(async () => {
        hInnerContract = await artifacts.require("InnerContract.sol").new();
        hOuterContract = await artifacts.require("OuterContract.sol").new();
    });

    describe('test:', async () => {
        let input = 1;
        it(`expected output = ${input + 1}`, async () => {
            try {
                let hash = await hOuterContract.func(input);
                let output = Number(hash.receipt.logs[0].data);
                assert(output == input + 1, `actual output = ${output}`);
            }
            catch (error) {
                assert(false, error.message);
            }
        });
    });
});

Das Problem liegt jedoch bei hash.receipt.logs[0].data.

Es enthält den Wert innerhalb des eventin der Funktion generierten InnerContract.

eventIch habe mir überlegt, dass ich auch in der Funktion generieren sollte OuterContract:

contract OuterContract {
    event Event(uint256);
    InnerContract pInnerContract;

    function func(uint256 val) external returns (uint256) {
        uint256 val2 = pInnerContract.func(val) + 1;
        Event(val2);
        return val2;
    }
}

Aber wenn ich das mache, bekomme ich die folgende Ausnahme in Trüffel:

Uncaught TypeError: Cannot read property 'constructor' of undefined
at C:\Users\...\cli.bundled.js:316118:19
at Array.forEach (<anonymous>)
at C:\Users\...\cli.bundled.js:316114:32
at Array.map (<anonymous>)
at Object.decodeLogs (C:\Users\...\cli.bundled.js:316067:19)
at Object.callback (C:\Users\...\cli.bundled.js:316195:35)
at C:\Users\...\cli.bundled.js:37985:25
at C:\Users\...\cli.bundled.js:328869:9
at C:\Users\...\cli.bundled.js:324536:9
at XMLHttpRequest.request.onreadystatechange (C:\Users\...\cli.bundled.js:327565:7)

Übrigens, bevor diese Ausnahme auftritt, zeigt truffle an, dass beide Ereignisse tatsächlich ausgegeben wurden:

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

Event(: 1)
Event(: 2)

---------------------------

Können Sie mir bitte erklären, was ich hier falsch mache?

Danke schön!!!

Antworten (2)

Es scheint, dass die Uncaught TypeError: Cannot read property 'constructor' of undefinedAusnahme behoben werden kann, indem die anonyme Variable in jedem der Ereignisse "benannt" wird.

Mit anderen Worten, jedes Auftreten davon ändern:

event Event(uint256);

Zu so etwas:

event Event(uint256 x);

Aus irgendeinem Grund funktioniert das "anonyme Ereignis" nur, solange ein einzelnes Ereignis ausgegeben wird.

Wenn ich Sie richtig verstanden habe, haben Sie einen internen Vertrag mit einem Funktionsnamen, der funceinfach einen Wert zurückgibt, und einen externen Vertrag , der dieselbe Funktion überschreibt. Der funcäußere Vertrag ruft den funcinneren Vertrag auf und addiert 1 zum zurückgegebenen Wert.

Stellen Sie den inneren Vertrag bereit

contract InnerContract {
    function func(uint256 val) external returns (uint256) {
        return val;
    }
}

Die Adresse des inneren Vertrages sei: 0xdc04977a2078c8ffdf086d618d1f961b6c546222.

Stellen Sie den äußeren Vertrag mit folgendem Code bereit:

pragma solidity ^0.4.18;
contract InnerContract {
    function func(uint256 val) external returns (uint256) {
    }
}

contract OuterContract is InnerContract{
    InnerContract pInnerContract = InnerContract(0xdc04977a2078c8ffdf086d618d1f961b6c546222);
   function func(uint256 val) external returns (uint256) {
        return  pInnerContract.func(val) + 1;
    }
}

Wenn Sie jetzt func_outermit dem Wert 1 aufrufen, ist der Rückgabewert 2.

"überschreibt dieselbe Funktion" - das ist falsch, ich überschreibe hier nichts. Es ist einfach eine (nicht konstante) Funktion, die eine nicht konstante Funktion aufruft. Und ich kann die äußere Funktion truffle testaufgrund einer seltsamen Ausnahme bei Trüffeln nicht mit testen.
Ja, das war mein Fehler. Bitte überprüfen Sie die Aktualisierungen.
Ich habe kein Problem beim Aufrufen der äußeren Funktion. Ich habe ein Problem damit, es aus dem JS-Skript aufzurufen (ein Teil meiner Frage, den Sie anscheinend völlig ignoriert haben) und den zurückgegebenen Wert abzurufen - etwas, das nur über Ereignisse erfolgen kann (ein weiterer Teil meiner Frage, auf den Sie nicht verwiesen haben Zu).