Hello,
I am wondering how can I go about mocking upgradeable contracts? Am I able to use libraries such as https://github.com/gnosis/mock-contract still or does OZ provide some mock helper?
Thanks in advance
Hello,
I am wondering how can I go about mocking upgradeable contracts? Am I able to use libraries such as https://github.com/gnosis/mock-contract still or does OZ provide some mock helper?
Thanks in advance
Hi @emobe,
There isn’t a mock helper as part of OpenZeppelin.
In OpenZeppelin Contracts, mock contracts are manually generated.
I haven’t used https://github.com/gnosis/mock-contract. If you are using a mock library, you may want to write unit tests that test just the logic contracts and have additional tests for testing as upgradeable contracts.
True, I can make the logic a separate contract. Would make it more SOLID.
Is there any reason not to use an upgradeable contract?
Hi @emobe,
I mean that for the one contract, you can create tests for the logic and tests for the upgradeability.
A very simple example is shown below (using OpenZeppelin Test Environment):
pragma solidity ^0.5.0;
contract Counter {
uint256 public value;
function increase() public {
value++;
}
}
const { accounts, contract, web3 } = require('@openzeppelin/test-environment');
const { TestHelper } = require('@openzeppelin/cli');
const { Contracts, ZWeb3 } = require('@openzeppelin/upgrades');
const {
BN, // Big Number support
constants, // Common constants, like the zero address and largest integers
expectEvent, // Assertions for emitted events
expectRevert, // Assertions for transactions that should fail
} = require('@openzeppelin/test-helpers');
ZWeb3.initialize(web3.currentProvider);
const Counter = Contracts.getFromLocal('Counter');
require('chai').should();
describe('Counter (upgradeable)', function () {
beforeEach(async function () {
this.project = await TestHelper();
this.proxy = await this.project.createProxy(Counter);
})
it('should have a value', async function () {
const result = await this.proxy.methods.value().call();
result.should.be.bignumber.equal('0');
})
it('should increase value', async function () {
await this.proxy.methods.increase().send();
const result = await this.proxy.methods.value().call();
result.should.be.bignumber.equal('1');
})
})
const { accounts, contract, web3 } = require('@openzeppelin/test-environment');
const {
BN, // Big Number support
constants, // Common constants, like the zero address and largest integers
expectEvent, // Assertions for emitted events
expectRevert, // Assertions for transactions that should fail
} = require('@openzeppelin/test-helpers');
const Counter = contract.fromArtifact('Counter');
require('chai').should();
describe('Counter (logic)', function () {
beforeEach(async function () {
this.counter = await Counter.new();
})
it('should have a value', async function () {
const result = await this.counter.value();
result.should.be.bignumber.equal('0');
})
it('should increase value', async function () {
await this.counter.increase();
const result = await this.counter.value();
result.should.be.bignumber.equal('1');
})
})
Aside from the benefits of using OpenZeppelin SDK upgradeable contracts, some reasons to not create a contract as upgradeable:
transfer
: OpenZeppelin upgradeable contracts affected by Istanbul hardforkAh yes, makes sense now as it doesn’t need to be initialised in order to be tested. Thanks for your help
Hi @emobe,
We still need to call any initializers in logic and upgradeable tests, to ensure that the contract is initialized.
A post was split to a new topic: How to test upgradeable contracts?