7

So I'm using truffle and I notice that I seem to be able to deploy a contract's bytecode by calling deployer.deploy(MyContract);

But I've also seen people run:

myContract = await MyContract.new();

in a unit test without ever calling deployer.deploy().

Is my understanding correct? Do these bits of code do the same thing?

Thanks!

2

Both of the above functions are used to deploy the contract to the network.

deployer.deploy(myContract);

is used in our migration file.

We can deploy our own version to the network using the .new() function:

MetaCoin.new().then(function(instance) {

// do something

console.log(instance.address);

}).catch(function(err) {

// do something

});
| improve this answer | |
  • When the test suite starts, the contract deployment code in the /migrations folder is run automatically correct? This is important for testing side effects of your deployment code. – emkman May 15 '18 at 19:15
2

They're both similar in that they deploy the contract. The difference is that .deploy() behaves like a singleton in that you can access the deployed instance with .deployed(). You typically use .new() in tests to avoid the possibility of any side-effects.

Here's an example:

Example.sol

pragma solidity ^0.4.23;

contract Example {
  uint256 public data;

  function set(uint256 _data) public {
    data = _data;
  }
}

Example.spec.js

const Example = artifacts.require('Example')

contract('Example', (accounts) => {
  let instance

  beforeEach('setup', async () => {
    instance = await Example.new()

    // second test will fail with `deployed()`
    //instance = await Example.deployed()
  })

  describe('test singleton', () => {
    it('should set data', async () => {
      assert.equal(await instance.data.call(), '0')
      const {receipt: {status}} = await instance.set(5)
      assert.equal(status, '0x01')
      assert.equal(await instance.data.call(), '5')
    })

    it('should not read previous data', async () => {
      // this will be `5` instead of `0` if using `deployed()`
      assert.equal(await instance.data.call(), '0')
    })
  })
})
| improve this answer | |
  • I've been using deployed in beforeEach and I had no inconsistency issues whatsoever. Could you elaborate on what are the fundamental differences, other than the singleton aspect? Or is that it? – Paul Razvan Berg Nov 20 '18 at 12:19
  • @PaulBerg that's the only difference that I know of. So you're saying that using deployed in beforeEach resets the contract? I just ran a quick test and that was not the case. See my updated answer – Miguel Mota Nov 20 '18 at 16:53
  • On a double check, no, it doesn't reset it! In my case, there's a mapping which is added a new object in beforeEach so I think that's why there are no side-effects. – Paul Razvan Berg Nov 20 '18 at 16:57
  • @PaulBerg makes sense – Miguel Mota Nov 20 '18 at 16:58
1

I think the difference is that new() simply deploys a new instance of the contract. But when a contract is deployed by deployer.deploy(), the new instance is saved in the migration for later use with MyContract.deployed(), etc.

| improve this answer | |

Your Answer

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

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