Multitest

Multitest

Sylvia exposes several types that build on top of the Multitest. These types are supposed to be used next to the types generated by contract and interface macros.

💡

The types are hidden behind the mt feature flag. We recommend enabling it in the dev-dependencies.

Example usage of utilities described on this page as well as ones defined on the generated types page:

use sylvia::cw_multi_test::IntoAddr;
use sylvia::multitest::App;
 
use super::interface::sv::mt::InterfaceProxy;
use super::sv::mt::{CodeId, CounterContractProxy};
 
#[test]
fn example_test() {
    // Define the [cosmwasm_std::Addr] of the message sender.
    let owner = "owner".into_addr();
    let dummy = "dummy".into_addr();
 
    // Initialize the [sylvia::multitest::App].
    let app = App::default();
 
    // Initialize the generated [contract::sv::mt::CodeId] by storing the contract code on the App.
    let code_id = CodeId::store_code(&app);
 
    // Initialize the contract by calling the [contract::sv::mt::CodeId::instantiate] method.
    let contract = code_id
        .instantiate(true)
        .with_label("MyContract")
        .call(&owner)
        .unwrap();
 
    // Send messages through the [sylvia::multitest::Proxy] as you would call the methods on
    // the contract type.
    contract.some_exec(dummy.to_string()).call(&owner).unwrap();
    contract.some_query(dummy.to_string()).unwrap();
 
    // Send interface messages the same way.
    contract
        .interface_exec(dummy.to_string())
        .call(&owner)
        .unwrap();
    contract.interface_query(dummy.to_string()).unwrap();
}

App

The App (opens in a new tab) is a wrapper around the cw-multi-test::App (opens in a new tab), stored inside the RefCell. It is done this way because the App (opens in a new tab) has to be passed by reference to multiple types, and we have to use the interior mutability to affect it's state.

Proxy

The Proxy (opens in a new tab) represents a single, initialized contract. It is generic over it, and the App on which it's installed. The Proxy is the structure through which you act on behalf of the contract, sending messages and querying the state.

💡

The Proxy (opens in a new tab) should not be constructed manually. Instead, create the contracts CodeId instance and call CodeId::instantiate, which returns the Proxy (opens in a new tab).

The Proxy (opens in a new tab) by itself doesn't have the methods defined in your contract. They are instead implemented via auto-generated traits by contract and interface macros. Import the generated proxy trait into your test scope to use these methods. If you want to learn more about the proxy traits, you can go to this section.

ExecProxy

The ExecProxy (opens in a new tab) is an intermediate type, for setting additional data for the execute messages. It's main functionality is the call (opens in a new tab) method, requiring the user to specify the caller of the message.

💡

The ExecProxy (opens in a new tab) should not be constructed manually. Instead, it's supposed to be returned by execute methods exposed in the proxy traits.

MigrateProxy

The MigrateProxy (opens in a new tab) is an intermediate type for setting additional data for the migrate messages. It's main functionality is the call (opens in a new tab) method, requiring the user to specify the caller of the message.

💡

The MigrateProxy (opens in a new tab) should not be constructed manually. Instead, it's supposed to be returned by migrate methods exposed in the proxy traits.