Introduction
Continue with my series, we will perform query
.
The query
is an action in order to get data from the contract.
Create message query smart contracts
Same as execute
, we need to define two structs QueryMsg
and QueryResponse
in the src/msg.rc
to visualize the data type we want to receive and respond. Insert the below code:
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub enum QueryMsg { Counter {}, } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)] #[serde(rename_all = "snake_case")] pub struct QueryResponse { pub counter: i32, }
QueryResponse
is response of the smart contract return when we perform query
with QueryMsg
. Same as the response from API, it returns json
data.
Next, create a file: query.rs
in the src
folder and import module query
to lib.rs
. Our lib.rs
will show:
pub mod contract; mod error; pub mod execute; pub mod msg; pub mod query; pub mod state; pub use crate::error::ContractError;
In the file query.rs
, we are implementing a function with the name query_counter
and we pass the deps
as a parameter. The function return a StdResult<Binary>
. Update the below code:
#[cfg(not(feature = "library"))] use cosmwasm_std::{to_binary, Binary, Deps, Env, StdResult}; use crate::msg::QueryResponse; use crate::state::STATE; pub fn query_counter(deps: Deps, _env: Env) -> StdResult<Binary> { let current_state = STATE.load(deps.storage)?; let counter = current_state.counter; let resp = to_binary(&QueryResponse { counter }).unwrap(); Ok(resp) }
That's right. Simple, we implement a logic to query data stored in smart contract.
We need to bind response to json
data with to_binary
function support from cosmwasm-std
.
And don't forget add an new entry point to src/contract.rs
:
#[cfg_attr(not(feature = "library"), entry_point)] pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> StdResult<Binary> { match msg { QueryMsg::Counter {} => query_counter(deps, env), } }
I think we have familiar with this syntax throughout of series.
The last entry point of our contract has appeared. We need to test it.
Testing module
Still in the file: src/query.rs
. and update the below code to bottom:
#[cfg(test)] mod tests { use crate::contract::{execute, instantiate, query}; use crate::msg::{ExecuteMsg, InstantiateMsg, QueryMsg, QueryResponse}; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info}; use cosmwasm_std::to_binary; const ADDR: &str = "addr1"; #[test] fn test_query() { let mut deps = mock_dependencies(); let env = mock_env(); let info = mock_info(ADDR, &[]); let expect_data_0 = to_binary(&QueryResponse { counter: 0 }).unwrap(); let expect_data_1 = to_binary(&QueryResponse { counter: 1 }).unwrap(); let msg = InstantiateMsg {}; let _resp = instantiate(deps.as_mut(), env.clone(), info.clone(), msg).unwrap(); // query one time. let msg = QueryMsg::Counter {}; let resp = query(deps.as_ref(), env.clone(), msg).unwrap(); assert_eq!(resp, expect_data_0); // query two time let msg = ExecuteMsg::Update {}; let _resp = execute(deps.as_mut(), env.clone(), info, msg).unwrap(); let msg = QueryMsg::Counter {}; let resp = query(deps.as_ref(), env, msg).unwrap(); assert_eq!(resp, expect_data_1); } }
In query
testing module, we will coverage all logic of the smart contract includes: create contract, execute contract, and query contract.
We create a module test and unit test function test_query
.
We still import all dependencies and create two values expected. One for getting state after instantiate contract, two for getting state after execute the contract.
Run cargo-test
in the terminal
If your output like below, everything is right:
running 1 test
test query::tests::test_query ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 2 filtered out; finished in 0.00s
Sumary
I mentioned all entry points of the smart contract, wrote logic attach test case for our logic of smart contract.
Next part, I will build and deploy our contract to testnet
network.
Thanks for reading and have a good day!
Top comments (0)