0

Here is my example contract (ignore the fact this could be pure, this is a simplified example and my real example is not a pure function, it changes state, but I can reproduce the bug with this simple example):

    pragma solidity ^0.5.0;
    contract Hello {
        function hello() external {
        }
    }

and unit test:

    const Hello = artifacts.require("./Hello.sol");
    contract("Hello", accounts => {
        it("should hello", async () => {
            const hello = await Hello.deployed();
            await hello.hello({from : accounts[0]});
        });
    });

the above works fine on truffle develop or on truffle migrate + Ganache (GUI or CLI).

Now if I want to have two unit tests (for simplicity I've done the same one twice, in reality I would use different unit tests)

    const Hello = artifacts.require("./Hello.sol");
    contract("Hello", accounts => {
        it("should hello", async () => {
            const hello = await Hello.deployed();
            await hello.hello({from : accounts[0]});
        });
        it("should hello", async () => {
            const hello = await Hello.deployed();
            await hello.hello({from : accounts[0]});
        });
    });

Again this works fine on truffle develop or on truffle migrate + Ganache (GUI or CLI).

Now if I want to reset the state of the contract between each unit test (imagine hello() changes the state and I want to revert back to the way it was for the next unit test), the way I've been doing it is like this

    const Hello = artifacts.require("./Hello.sol");
    contract("Hello", accounts => {
        it("should hello", async () => {
            const hello = await Hello.deployed();
            await hello.hello({from : accounts[0]});
        });
    });
    contract("Hello", accounts => {
        it("should hello", async () => {
            const hello = await Hello.deployed();
            await hello.hello({from : accounts[0]});
        });
    });

this works fine if I just do this under truffle develop. But if I try to use truffle migrate + Ganache (GUI or CLI) I get an error like this:

Error: the tx doesn't have the correct nonce. account has nonce of: 162 tx has nonce of: 163

the numbers don't have to be exactly 162 and 163, I've just been running the example a lot, it could be 1 and 2. But they are always out of sync by one if I call contract twice in the unit test but not when I call it twice within one call to contract.

  • Use a single contract per unit-test (i.e., per JS file located under the test folder). – goodvibration Jul 1 at 16:51
  • The reason I was using multiple contract is if you use one, the state persists from one unit test to the next and I need it to reset. How do I avoid state persisting between tests? – Dr Lee A. Christie Jul 1 at 18:19
  • The state do not persist! You must be doing something wrong somewhere else. Try to "disable the activity" in your 1_initial_migration.js file (something like, do it only if (network !== "development")). – goodvibration Jul 2 at 5:18
  • what does "disable the activity" mean? Can you give an example of how 1_initial_migration.js should look? I just created a new fresh test project to make sure I haven't set anything up wrong. Having the state persist between tests seems to be the default behaviour for truffle test. Here's all the code in the new project: pastebin.com/ugBPLu86 – Dr Lee A. Christie Jul 2 at 10:26
  • Just get rid of your 1_deploy_contracts.js file (btw, its name should start with 2 I believe), and change Hello.deployed() to new Hello() in all your tests. – goodvibration Jul 2 at 10:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.