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)