VM Exception testing a logic contract that uses initializers

Getting this error when trying to use openzepplin-ethereum with box.js.

Any ideas?
1) Box
retrieve returns a value previously stored:

     Error: Returned error: VM Exception while processing transaction: revert Ownable: caller is not the owner -- Reason given: Ownable: caller is not the owner.
      at Context.<anonymous> (test/Box.test.js:19:25)
      at processTicksAndRejections (internal/process/task_queues.js:97:5)

Box.sol

   // contracts/Box.sol
// SPDX-License-Identifier: MIT
    pragma solidity ^0.6.0;

    // Import Ownable from the OpenZeppelin Contracts Ethereum Package library
    import "@openzeppelin/contracts-ethereum-package/contracts/access/Ownable.sol";
    import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol";

    // Make Box inherit from the Ownable contract
    contract Box is OwnableUpgradeSafe {
        uint256 private value;

        event ValueChanged(uint256 newValue);

        function initialize() public initializer {
            OwnableUpgradeSafe.__Ownable_init();
        }

        // The onlyOwner modifier restricts who can call the store function
        function store(uint256 newValue) public onlyOwner {
            value = newValue;
            emit ValueChanged(newValue);
        }

        function retrieve() public view returns (uint256) {
            return value;
        }
    }

Box.test.js

    const { accounts, contract } = require('@openzeppelin/test-environment');
    const { expect } = require('chai');

    // Load compiled artifacts
    const Box = contract.fromArtifact('Box');

    // Start test block
    describe('Box', function () {
      const [ owner ] = accounts;

      beforeEach(async function () {
        // Deploy a new Box contract for each test
        this.contract = await Box.new({ from: owner });
      });

      // Test case
      it('retrieve returns a value previously stored', async function () {
        // Store a value - recall that only the owner account can do this!
        await this.contract.store(42, { from: owner });

        // Test if the returned value is the same one
        // Note that we need to use strings to compare the 256 bit integers
        expect((await this.contract.retrieve()).toString()).to.equal('42');
      });
    });

Any ideas/tips.

Thank you all

1 Like

Hi @apple,

When testing a logic contract that uses initializers we need to call initialize.
(For more details on initializers see the Learn guides on Initialization)

        await this.contract.initialize({ from: owner });

The full test is as follows:

Box.test.js

const { accounts, contract } = require('@openzeppelin/test-environment');
const { expect } = require('chai');

// Load compiled artifacts
const Box = contract.fromArtifact('Box');

// Start test block
describe('Box', function () {
    const [owner] = accounts;

    beforeEach(async function () {
        // Deploy a new Box contract for each test
        this.contract = await Box.new({ from: owner });

        await this.contract.initialize({ from: owner });
    });

    // Test case
    it('retrieve returns a value previously stored', async function () {
        // Store a value - recall that only the owner account can do this!
        await this.contract.store(42, { from: owner });

        // Test if the returned value is the same one
        // Note that we need to use strings to compare the 256 bit integers
        expect((await this.contract.retrieve()).toString()).to.equal('42');
    });
});

As an aside, when posting code in the forum you can get it to format using the following:
```
Code goes here
```

thank you! that solved the issue!

1 Like