- Docs
- Smart Contracts
- Examples
Examples
To use cw-multi-test, you need to understand a few key concepts:
- App: Represents the simulated blockchain application, tracking block height and time. You can modify the environment to simulate multiple blocks, using methods like
app.update_block(next_block)
. - Mocking Contracts: You must mock or wrap contracts using ContractWrapper to test them within the multi-test environment.
Example: setting up and testing with cw-multi-test
Step 1: create a mock app
fn mock_app() -> App { let env = mock_env(); let api = Box::new(MockApi::default()); let bank = BankKeeper::new(); App::new(api, env.block, bank, Box::new(MockStorage::new()))}
Step 2: mock and wrap contracts
pub fn contract_counter() -> Box<dyn Contract<Empty>> { let contract = ContractWrapper::new( execute, instantiate, query, ); Box::new(contract)}
Step 3: store and instantiate the contract
let contract_code_id = router.store_code(contract_counter());let mocked_contract_addr = router .instantiate_contract(contract_code_id, owner.clone(), &init_msg, &[], "counter", None) .unwrap();
Step 4: execute and query the contract
let msg = ExecuteMsg::Increment {};let _ = router.execute_contract( owner.clone(), mocked_contract_addr.clone(), &msg, &[],).unwrap();let config_msg = QueryMsg::Count {};let count_response: CountResponse = router .wrap() .query_wasm_smart(mocked_contract_addr.clone(), &config_msg) .unwrap();assert_eq!(count_response.count, 1);
Mocking third-party contracts
Mocking third-party contracts, such as those from protocols like Terraswap or Anchor, can be challenging since these protocols often don't include the contract code in their Rust packages. However, you can create a thin mock of the service you interact with by implementing only the functions and queries you need.
Example
pub fn contract_ping_pong_mock() -> Box<dyn Contract<Empty>> { let contract = ContractWrapper::new( |deps, _, info, msg: MockExecuteMsg| -> StdResult<Response> { match msg { MockExecuteMsg::Receive(Cw20ReceiveMsg { sender: _, amount: _, msg }) => { let received: PingMsg = from_binary(&msg)?; Ok(Response::new() .add_attribute("action", "pong") .set_data(to_binary(&received.payload)?)) } } }, |_, _, msg: MockQueryMsg| -> StdResult<Binary> { match msg { MockQueryMsg::Pair {} => Ok(to_binary(&mock_pair_info())?), } }, ); Box::new(contract)}