3
votes

background

I have written an ethereum smart-contract in the Solidity language. In order to test things, I can run a local node using Ganache and deploy my contract on it using truffle migrate.

requirements

I want to test my contract using JavaScript. I want to create a new instance of my contract for each test.

what i've tried

I created a test file tests/test.js in my project:

const expect = require('chai').expect

const Round = artifacts.require('Round')


contract('pledgersLength1', async function(accounts) {
    it('1 pledger', async function() {
        let r = await Round.deployed()
        await r.pledge(5)
        let len = (await r.pledgersLength()).toNumber()
        expect(len).to.equal(1)
    })
})
contract('pledgersLength2', async function(accounts) {
    it('2 pledgers', async function() {
        let r = await Round.deployed()
        await r.pledge(5)
        await r.pledge(6)
        let len = (await r.pledgersLength()).toNumber()
        expect(len).to.equal(2)
    })
})

I run it with truffle test. It's basically Mocha, but truffle defines artifacts for you with a JavaScript connection to the smart contracts.

The truffle contract function is almost the same as Mocha's describe function, with a small change that I don't understand! I assumed that contract would make my contract new each time. It doesn't. Perhaps I can use something like new Round() instead of Round.deployed(), but I just don't know how.

The solution does not have to use truffle.

1
Are you sure it is not the same contract? On their site they claim that is will be a new contract instance in every describe function. How do you know that is the same instance? - nikos fotiadis
@nikosfotiadis I am sure. The way that I know is probably irrelevant to the question, but if you try to pledge the same amount twice, the contract will error. So in the example I typed above, I get an error when I expect to not get an error. - mareoraft
@ZulhilmiZainudin Yes, using .new() instead of .deployed() is working like a charm! That should really be added to the truffle documentation. Could you post it as an answer? - mareoraft
I'm glad it helped. I've posted my answer. Appreciate if you can upvote and accept it. - Zulhilmi Zainudin

1 Answers

4
votes

Please note that .new and .deployed are not the same. See what I've found here.

Follow this example and it should solve your problem:

// Path of this file: ./test/SimpleStorage.js
var simpleStorage = artifacts.require("./SimpleStorage.sol");

contract('SimpleStorage', function(accounts) {

  var contract_instance;

  before(async function() {
    contract_instance = await simpleStorage.new();
  });

  it("owner is the first account", async function(){
    var owner = await contract_instance.owner.call();
    expect(owner).to.equal(accounts[0]);
  });

});

The .new keyword will deploy an instance of your contract in a new context.

But, .deployed will actually use the contract that you have deployed earlier i.e. when you are using truffle migrate command.

In the context of unit test, it's better to use .new so that you will always start with fresh contract.