Closed vmsh0 closed 3 years ago
Hey @vmsh0 !
It actually doesn't work with abstract contracts but for sure you can use the interface or the abi!
Please check out the docs to see how to do it. If you want more detailed example you could check this tests.
If you think the documentation is not clear enough, we would appreciate a PR with your improvements!
Hope that helps
Apologies - I didn't explain myself well enough! :)
I actually have a contract which is an interface, and I'd like to mock that.
I.e.
interface IWhateverInterface
{
function setSomething(address a, address b) external;
}
Obviously I cannot create a contract factory for this contract. Nor (as far as I can see) can I get an Abi
object for it from Ethers and pass it to the Fake
constructor. But it would be nonetheless useful to be able to mock an interface without having to creare a mock Solidity implementation - which I think it's the entire point of this plugin.
Am I missing something?
You should be able to use the abi of the interface actually.
Is your interface inside your contracts
directory? If it is, hardhat will generate an artifact for it. Look into your artifacts directory for the generated file, it will be something like:
import ICookieArtifact from 'artifacts/contracts/interfaces/ICookie.sol/ICookie.json';
Then you will be able to use the artifact by doing:
await smock.fake(ICookieArtifact);
or
await smock.fake(ICookieArtifact.abi);
Ok, this does work! It's a bit rough on the edges, but it should do fine. Thank you for your help!
Do you have any ideas for improvements? They are more than welcome
The pattern for loading the ABI of concrete contracts is:
1) load the contract with ethers.getContractFactory()
2) pass the result to fake
This abstracts away the details of how the ABI is stored in the filesystem. So it seems natural to me that loading the ABI of an abstract contract should follow at best a similar pattern:
1) load the ABI with some method which takes care of the filesystem representation (can Ethers do that?)
2) pass the result to fake
I'm quite a beginner when it comes to Ethers - I only just got started with it. So I'm not sure whether it has the capability of loading the ABI of an abstract contract. In case it hasn't, I'm not sure whether Smock should implement it by itself.
Although, I would prepend for a "no" - smearing abstractions around different libraries is probably worse than just not having a complete abstraction covering all cases. Ethers should probably do that - what do you think? If you agree, I might just open an issue on their repo referencing this one and see what they think about it.
Actually, when building the V2, we first tried abstracting the abi extraction as you said, but it actually compromised the UX...
The previous solution was to ask users to call ethersInterfaceFromSpec, and then we would simply receive the interface as a ethers.utils.Interface
.
I totally agree with you from a smock programmer point of view, the issue is that for every fake you will get 2 lines of code, making the user experience a bit rougher...
Then, maybe a solution is to accept both ways? If you wanna chat about possible improvements/ideas, join our discord server (you can find it on the README). As well, feel free to submit any PRs, we are definitely looking for some help supporting Smock
Is your feature request related to a problem? Please describe. I have an interface. I have to create a mock contract implementing that interface.
Describe the solution you'd like I would like to be able to initialize a Fake using an interface (or in general any abstract contract). E.g.
const myFake = await smock.fake("AnAbstractContract")
Describe alternatives you've considered Manually specifying the ABI in the initialization call.