5

I am instantiating a contract to test like this:

var Test = artifacts.require("./Test.sol");

contract('Test0', function(accounts) {
  it("First test", function() {
    var thisTest
    return Test.deployed().then(function(instance) {
    thisTest = instance
    // my tests
  })

  it("Second test", function() {
    var thisTest
    return Test.deployed().then(function(instance) {
    thisTest = instance
    // thisTest still refers to the one in the previous test
    // How do I create a new one?
  })
})

The problem I'm having is that I can't isolate the different instances as I assume they're pointing to only one instance of the contract.

Is there a way to create more than one instance?

2 Answers 2

2

It doesn't make much sense to have two instances of the same contract since both instances would be referring to the same contract and share the same state variables. Do you mean you want to redeploy your contract on the blockchain such that your two contracts have the same code, but located at different contract address on the blockchain?

For testing purpose, you can have:

var Test = artifacts.require("./Test.sol");

contract('Test0', function(accounts) {
  it("First test", function() {
    var thisTest
    return Test.deployed().then(function(instance) {
    thisTest = instance
    // my tests
  })

  it("Second test", function() {
    var thisTest
    return Test.deployed().then(function(instance) {
    thisTest = instance
  })
})

contract('Test1', function(accounts) {
  it("Third test", function() {
    var thisTest
    return Test.deployed().then(function(instance) {
    thisTest = instance
  })

  it("Forth test", function() {
    var thisTest
    return Test.deployed().then(function(instance) {
    thisTest = instance
  })
})

Each time you call contract(), it redeploys the contract and each test case within the function share the same contract. For example, the code above would have 1st and 2nd test run on the same contract, and then it would redeploy your contract to a new contract address and have 3rd and 4th test run there.

1
2

deployed() is meant as a singleton, i.e., first time called it will deploy the contract and on second call it will return the same instance. If you want a new instance every time then use Test.new() like so:

var Test = artifacts.require("./Test.sol");

contract("Test", async (accounts) => {
  it("should be initialized twice", async () => {
    let instance1 = await Test.new();
    let instance2 = await Test.new();
    assert.notEqual(instance1.address, instance2.address);
  });
});

Also a possible solution is as @longcc is suggesting. Each test suite starts with a fresh migration, which means that your deploy in migration scripts is rerun and you should see a new instance returned when calling Contract.deployed() in your tests. However, I've observed some issues with it in the past, see https://github.com/trufflesuite/truffle/issues/848, therefore I think it's a safer bet to use Contract.new.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.