mock_call
def mock_call(contract_address: int, fn_name: str, ret_data: Union[List[int], Dict]) -> Callable: ...
Mocks all calls to function with the name fn_name
of a contract with an address contract_address
, until the returned callable is called.
Mocked call returns data provided in ret_data
.
Mock works globally, for all contracts, not only the testing contract.
Caveats
- Mock call only works for functions that are in the contract ABI. It does not mock any internal function calls, even if the function name and parameter types match.
tip
You can provide constructor arguments as a dictionary to leverage data transformer.
Representing different data structures in ret_data
To use mock_call
effectively, you need to understand how Cairo data structures are represented under the hood. Cairo-lang
operates on a list of integers. The following examples demonstrate how each data structure is represented in Python code.
Felt
mocked_call returns a felt
%lang starknet
@contract_interface
namespace ITestContract {
func get_felt() -> (res: felt) {
}
}
const EXTERNAL_CONTRACT_ADDRESS = 0x3fe90a1958bb8468fb1b62970747d8a00c435ef96cda708ae8de3d07f1bb56b;
@external
func test_mock_call_returning_felt{syscall_ptr: felt*, range_check_ptr}() {
tempvar external_contract_address = EXTERNAL_CONTRACT_ADDRESS;
%{ stop_mock = mock_call(ids.external_contract_address, "get_felt", [42]) %}
let (res) = ITestContract.get_felt(EXTERNAL_CONTRACT_ADDRESS);
%{ stop_mock() %}
assert res = 42;
return ();
}
Array
To mock a function returning an array, provide data in the following format to ret_data
:
Python representation of a Cairo array
[n, value_1, value_2, ..., value_n]
mocked_call returns an array
%lang starknet
@contract_interface
namespace ITestContract {
func get_array() -> (res_len: felt, res: felt*) {
}
}
const EXTERNAL_CONTRACT_ADDRESS = 0x3fe90a1958bb8468fb1b62970747d8a00c435ef96cda708ae8de3d07f1bb56b;
@external
func test_mock_call_returning_array{syscall_ptr: felt*, range_check_ptr}() {
tempvar external_contract_address = EXTERNAL_CONTRACT_ADDRESS;
%{ stop_mock = mock_call(ids.external_contract_address, "get_array", [1, 42]) %}
let (res_len, res_arr) = ITestContract.get_array(EXTERNAL_CONTRACT_ADDRESS);
%{ stop_mock() %}
assert res_arr[0] = 42;
return ();
}
Struct
mocked_call returns a struct
%lang starknet
struct Point {
x: felt,
y: felt,
}
@contract_interface
namespace ITestContract {
func get_struct() -> (res: Point) {
}
}
const EXTERNAL_CONTRACT_ADDRESS = 0x3fe90a1958bb8468fb1b62970747d8a00c435ef96cda708ae8de3d07f1bb56b;
@external
func test_mock_call_returning_struct{syscall_ptr: felt*, range_check_ptr}() {
tempvar external_contract_address = EXTERNAL_CONTRACT_ADDRESS;
%{ stop_mock = mock_call(ids.external_contract_address, "get_struct", [21,37]) %}
let (res_struct) = ITestContract.get_struct(EXTERNAL_CONTRACT_ADDRESS);
%{ stop_mock() %}
assert res_struct.x = 21;
assert res_struct.y = 37;
return ();
}