Mocks¶
What are mocks?¶
Mocks are extensions to smart contracts that have all of the functionality of a fake with some extra goodies. Behind every mock is a real smart contract (with actual Solidity code!) of your choosing. You can modify the behavior of functions like a fake, or you can leave the functions alone and calls will pass through to your actual contract code. And, with a little bit of smock magic, you can even modify the value of variables within your contract! 🥳
When should I use a mock?¶
Generally speaking, mocks are more advanced versions of fakes. Mocks are most effectively used when you need some behavior of a real smart contract but still want the ability to modify things on the fly.
One powerful feature of a mock is that you can modify the value of variables within the smart contract. You could, for example, use this feature to test the behavior of a function that changes behavior depending on the value of a variable.
Using mocks¶
Initialization¶
Initialize with a contract name¶
const myContractFactory = await smock.mock('MyContract');
const myContract = await myContractFactory.deploy(...);
Take full advantage of typescript and typechain¶
await smock.mock<MyContract__factory>('MyContract');
Options¶
await smock.mock('MyContract', { ... }); // how to use
// options
{
provider?: Provider; // initialize mock with a custom provider
}
Using features of fakes¶
Mocks can use any feature available to fakes. See the documentation of fakes for more information.
Call through¶
Calls go through to contract by default¶
await myMock.add(10);
await myMock.count(); // returns 10
myMock.count.returns(1);
await myMock.count(); // returns 1
Manipulating variables¶
Warning
This is an experimental feature and it is subject to API changes in the near future
Setting the value of a variable¶
await myMock.setVariable('myVariableName', 1234);
Setting the value of a struct¶
await myMock.setVariable('myStruct', {
valueA: 1234,
valueB: true,
});
Setting the value of a mapping (won’t affect other keys)¶
await myMock.setVariable('myMapping', {
myKey: 1234
});
Setting the value of a nested mapping¶
await myMock.setVariable('myMapping', {
myChildMapping: {
myKey: 1234
}
});
Setting the value of multiple variables¶
await myMock.setVariables({
myVariableName1: 123,
myVariableName2: true,
myStruct: {
valueA: 1234,
valueB: false,
},
myMapping: {
[myKey]: 1234
}
})
Getting the value of an internal variable¶
Warning
This is an experimental feature and it does not support multidimensional or packed arrays
const myUint256 = await myMock.getVariable('myUint256VariableName');
Getting the value of an internal mapping given the value’s key¶
const myMappingValue = await myMock.getVariable('myMappingVariableName', [mappingKey]);
Getting the value of an internal nested mapping given the value’s keys¶
const myMappingValue = await myMock.getVariable('myMappingVariableName', [mappingKeyA, mappingKeyB]);