cargo_fixture/
client_test.rs

1use serde::de::DeserializeOwned;
2
3use crate::{
4    rpc_socket::{ConnectionType, Request, RpcSocket},
5    Result,
6};
7
8/// An RPC client used from test code.
9///
10/// An instance is created using [`TestClient::connect()`],
11/// it's more convenient to use the [`with_fixture`][crate::with_fixture] macro.
12pub struct TestClient {
13    socket: RpcSocket,
14}
15
16impl TestClient {
17    /// Connect to running `cargo fixture` process.
18    ///
19    /// The `serial` argument is a way to create a serial test. When set to `true`,
20    /// `cargo fixture` will make sure that no other test client is connected at the same time.
21    /// That is, if any other tests are already running, it will wait for them to finish,
22    /// then let this connection proceed, and only let other connections in once this one is finished.
23    pub async fn connect(serial: bool) -> Result<Self> {
24        RpcSocket::connect(ConnectionType::client(serial))
25            .await
26            .map(|socket| Self { socket })
27    }
28
29    /// Get a copy of a value from `cargo fixture`'s in-memory K-V store.
30    ///
31    /// The value expected to have been prepared by the fixture. It can be any serde-serializable value.
32    pub async fn get_value<T>(&mut self, key: impl Into<String>) -> Result<T>
33    where
34        T: DeserializeOwned,
35    {
36        let req = Request::GetKeyValue { key: key.into() };
37        let value = self.socket.call(req).await?.as_value()?;
38        serde_json::from_value(value).map_err(Into::into)
39    }
40}