I have some self defined deserialize functions, how to test them? the serde_test crate does not provide function unit tests.
fn deserialize_string_to_size<'de, D>(deserializer: D) -> std::result::Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
let (size_num, unit) = parse_string_to_num_and_unit(&s)?;
match unit {
"kb" => Ok(size_num * KB),
"mb" => Ok(size_num * MB),
"gb" => Ok(size_num * GB),
"tb" => Ok(size_num * TB),
"pb" => Ok(size_num * PB),
_ => Err(de::Error::missing_field("size")),
}
}
fn parse_string_to_num_and_unit<E: de::Error>(s: &str) -> std::result::Result<(u64, &str), E> {
if !s.starts_with(char::is_numeric) {
return Err(E::custom("missing number in configuration"));
}
let (h, u) = s.split_at(
s.chars()
.position(|x| x.is_alphabetic())
.ok_or_else(|| E::custom("expecting unit in configuration"))?,
);
Ok((
h.parse()
.map_err(|e| E::custom(format!("parsing number error: {}", e)))?,
u,
))
}
How can I test these 2 fns?
Maybe create a newtype that wraps a string and use #[serde(with = ...)]
to make it use your functions, then use the normal testing facilities on this type.
How about writing tests like this?
#[cfg(test)]
mod tests {
use serde::Deserialize;
use super::deserialize_string_to_size;
use super::KB;
#[derive(Deserialize, Debug)]
struct Example(#[serde(deserialize_with = "deserialize_string_to_size")] u64);
#[test]
fn size1() {
let json = r#""12kb""#;
let e: Example = serde_json::from_str(json).unwrap();
assert_eq!(e.0, 12 * KB)
}
}
1 Like
Hi thanks for your advice, I find a way to test it
#[test]
fn test_deserialize_string_to_size() {
assert_eq!(
10 * KB,
deserialize_string_to_size(toml::Value::String("10kb".into())).unwrap()
);
assert_eq!(
10 * MB,
deserialize_string_to_size(toml::Value::String("10mb".into())).unwrap()
);
assert_eq!(
10 * GB,
deserialize_string_to_size(toml::Value::String("10gb".into())).unwrap()
);
assert_eq!(
10 * TB,
deserialize_string_to_size(toml::Value::String("10tb".into())).unwrap()
);
assert!(deserialize_string_to_size(toml::Value::String("kb".into())).is_err());
assert!(deserialize_string_to_size(toml::Value::String("10".into())).is_err());
}