This crate allows emulating ethereum node with a limited number of supported RPC calls, enabling you to mock ethereum contracts.
Create a new deployment using the [Mock::deploy] function.
Configure contract's behaviour using [Contract::expect_transaction]
and [Contract::expect_call].
Finally, create an ethcontract's Instance by calling [Contract::instance],
then use said instance in your tests.
Example
Let's mock voting contract from solidity examples.
First, we create a mock node and deploy a new mocked contract:
# include!;
#
# async
Then we set up expectations for method calls:
# include!;
#
# async
Finally, we create a dynamic instance and work with it as usual:
# include!;
#
# async
Describing expectations
The mocked contracts have an interface similar to the one
of the [mockall] crate.
For each contract's method that you expect to be called during a test,
call [Contract::expect_transaction] or [Contract::expect_call]
and set up the created [Expectation] with functions such as returns,
times, in_sequence. For greater flexibility, you can have
multiple expectations attached to the same method.
See [Expectation] for more info and examples.
Interacting with mocked contracts
After contract's behaviour is programmed, you can call
[Contract::instance] to create an ethcontract's Instance.
You can also get contract's address and send RPC calls directly
through web3.
Specifically, mock node supports eth_call, eth_sendRawTransaction,
and eth_getTransactionReceipt.
At the moment, mock node can't sign transactions on its own,
so eth_sendTransaction is not supported. Also, deploying contracts
via eth_sendRawTransaction is not possible yet.
Mocking generated contracts
Overall, generated contracts are similar to the dynamic ones:
they are deployed with [Mock::deploy] and configured with
[Contract::expect_call] and [Contract::expect_transaction].
You can get generated contract's ABI using the raw_contract function.
Generated method signatures are available through the signatures
function.
Finally, type-safe instance can be created using the at method.
Here's an example of mocking an ERC20-compatible contract.
First, we create a mock node and deploy a new mocked contract:
# include!;
# /*
ethcontract::contract!("ERC20.json");
# */
# contract!;
#
# async
Then we set up expectations using the generated method signatures:
# include!;
# contract!;
#
# async
Finally, we use mock contract's address to interact with the mock node:
# include!;
# contract!;
#
# async
Mocking gas and gas estimation
Mock node allows you to customize value returned from eth_gasPrice
RPC call. Use [Mock::update_gas_price] to set a new gas price.
Estimating gas consumption with eth_estimateGas is not supported at the
moment. For now, calls to eth_estimateGas always return 1.