I'm trying to test a Custom RPC. Let's make it a simple pass through.
p_api::decl_runtime_apis! {
pub trait SimpleApi<AccountId> where
AccountId: Codec,
{
fn is_true() -> Result<bool, DispatchError>;
}
}
Client Server Trait
#[rpc(client, server)]
pub trait SimpleApi<BlockHash, AccountId> {
#[method(name = "simple_isTrue")]
fn is_true(
&self,
) -> RpcResult<bool>>;
}
pub struct SimpleHandler<C, M> {
client: Arc<C>,
_marker: std::marker::PhantomData<M>,
}
impl<C, M> SimpleHandler<C, M> {
pub fn new(client: Arc<C>) -> Self {
Self { client, _marker: Default::default() }
}
}
#[async_trait]
impl<C, Block, AccountId> SimpleServer<<Block as BlockT>::Hash, AccountId> for SimpleHandler<C, Block>
where
Block: BlockT,
C: Send + Sync + 'static,
C: ProvideRuntimeApi<Block>,
C: HeaderBackend<Block>,
C::Api: SimpleRuntimeApi<Block, AccountId>,
AccountId: Codec,
{
fn is_true(&self) -> RpcResult<bool> {
let api = self.client.runtime_api();
let at = BlockId::hash(self.client.info().best_hash);
let runtime_api_result = api.is_true(&at);
map_rpc_result(runtime_api_result)
}
}
So following the test setup from https://github.com/paritytech/substrate/blob/master/client/rpc/src/author/tests.rs
use substrate_test_runtime_client::{
runtime::Block, Client, Backend, DefaultTestClientBuilderExt,
};
struct TestSetup {
pub client: Arc<Client<Backend>>
}
impl Default for TestSetup {
fn default() -> Self {
let client_builder = substrate_test_runtime_client::TestClientBuilder::new();
let client = Arc::new(client_builder.build());
TestSetup { client }
}
}
impl TestSetup {
fn simple(&self) -> SimpleHandler<Client<Backend>,Block> {
SimpleHandler {
client: self.client.clone(),
_marker: Default::default(),
}
}
fn into_rpc() -> RpcModule<SimpleHandler<Client<Backend>, Block>> {
Self::default().simple().into_rpc()
}
}
#[tokio::test]
async fn testing_simple() {
let api = TestSetup::default().simple();
let rpc = api.into_rpc();
let response = rpc.call("").await.unwrap();
}
This fails with:
let rpc = api.into_rpc();
^^^^^^^^ method cannot be called on `SimpleHandler<...>` due to unsatisfied trait bounds
// ...
C::Api: SimpleRuntimeApi<Block, AccountId>,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced here
Which makes since, as nothing in the test setup has an implementation for SimpleRuntimeApi
. So how do I mock one and tell the client?
My assumption is that I am missing part of the setup for substrate_test_runtime_client (Or perhaps I should actually be using substrate_test_client ?) but the examples around it are few. Always possible I'm barking up the wrong tree entirely.