-
Hi there, congratulations for the great Just a quick question, does the library support some kind of mock Client for testing, similar to rusoto_mock for rusoto? I would like to unit-test the logic for parsing responses from the k8s API, but couldn't seem to find examples. Thanks, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
Hey there. Not at the moment unfortunately, it's something I want as well though, and it's more possible now that we have service/client distinction. Actually had a little bit of a go at creating a The problem; |
Beta Was this translation helpful? Give feedback.
-
For now, you can use |
Beta Was this translation helpful? Give feedback.
-
Hi Team Is there any update on this? The above suggested mock approach works for one time. I am not able to make it work for two api calls in the same test. Below is a sample function to demonstrate the problem. In function we are first checking if a kubernetes secret exist, if not then create it or else update it. use k8s_openapi::api::core::v1::Secret;
use kube::{
api::{Api, ObjectMeta, PostParams},
Error as KubeError,
};
use reqwest::StatusCode;
use std::collections::BTreeMap;
async fn set_k8_single_secret(
client: &Api<Secret>,
key: &str,
value: &str,
) -> Result<(), KubeError> {
match client.get(key).await {
Ok(mut secret) => {
let mut data: BTreeMap<String, String> = BTreeMap::new();
data.insert(key.to_string(), value.to_string());
secret.string_data = Some(data);
client.replace(key, &PostParams::default(), &secret).await
}
Err(KubeError::Api(e)) if e.code == StatusCode::NOT_FOUND => {
let mut data: BTreeMap<String, String> = BTreeMap::new();
data.insert(key.to_string(), value.to_string());
let metadata = ObjectMeta {
name: Some(key.to_string()),
..Default::default()
};
let secret = Secret {
metadata,
string_data: Some(data),
..Default::default()
};
client.create(&PostParams::default(), &secret).await
}
Err(e) => Err(e),
}
.map(|_| Ok(()))?
} Below is the test case for it. Just for clarity, I know problem is not with mod test {
use http::{Request, Response};
use k8s_openapi::api::core::v1::Secret;
use tower_test::mock;
use kube::{client::Body, Api, Client};
#[tokio::test]
async fn set_k8_single_secret_create() {
let key = "key";
let (mock_service, mut handle) = mock::pair::<Request<Body>, Response<Body>>();
handle.allow(2);
let spawned = tokio::spawn(async move {
let (request, send) = handle.next_request().await.expect("service not called");
let status_code = match request.method() {
&http::Method::GET
if format!("/api/v1/namespaces/default/secrets/{}", key)
== request.uri().to_string().as_str() =>
{
println!("received GET operation");
http::StatusCode::NOT_FOUND
}
&http::Method::POST
if "/api/v1/namespaces/default/secrets".to_string()
== request.uri().to_string() =>
{
println!("received CREATE operation");
http::StatusCode::OK
}
_ => panic!("unexpected url or method"),
};
send.send_response(
Response::builder()
.status(status_code)
.body(Body::from(serde_json::to_vec("{}").unwrap()))
.unwrap(),
);
});
let secrets: Api<Secret> = Api::default_namespaced(Client::new(mock_service, "default"));
assert!(crate::backend::tmp::set_k8_single_secret(&secrets, key, key).await.is_ok());
spawned.await.unwrap();
}
} |
Beta Was this translation helpful? Give feedback.
For now, you can use
tower_test::mock
like this example: https://github.com/clux/kube-rs/pull/430/filesWe'd like to provide something more convenient.