Как выполнить модульное тестирование функции десериализации, используемой в serde (deserialize_with)? - PullRequest
2 голосов
/ 11 июля 2019

У меня есть структура, которая реализует Deserialize и использует serde(deserialize_with) в поле:

#[derive(Debug, Deserialize)]
struct Record {
    name: String,
    #[serde(deserialize_with = "deserialize_numeric_bool")]
    is_active: bool,
}

Реализация deserialize_numeric_bool десериализует строку «0» или «1» до соответствующего логического значения:

pub fn deserialize_numeric_bool<'de, D>(deserializer: D) -> Result<bool, D::Error>
    where D: Deserializer<'de>
{
    struct NumericBoolVisitor;

    impl<'de> Visitor<'de> for NumericBoolVisitor {
        type Value = bool;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("either 0 or 1")
        }

        fn visit_u64<E>(self, value: u64) -> Result<bool, E>
            where E: DeserializeError
        {
            match value {
                0 => Ok(false),
                1 => Ok(true),
                _ => Err(E::custom(format!("invalid bool: {}", value))),
            }
        }
    }

    deserializer.deserialize_u64(NumericBoolVisitor)
}

(я ценю комментарии об улучшениях кода)

Я бы хотел написать модульные тесты для функций десериализации, такие как deserialize_numeric_bool. Конечно, в моем дружественном окне поиска были обнаружены serde_test корзина и страница документации о юнит-тестировании . Но эти ресурсы не могли помочь мне в моем случае, так как корзина тестирует структуру, непосредственно реализующую Deserialize.

У меня была одна идея - создать новый тип, содержащий только выходные данные моих десериализованных функций, и протестировать его с ним. Но это выглядит для меня ненужным косвенным указанием.

#[derive(Deserialize)]
NumericBool {
    #[serde(deserialize_with = "deserialize_numeric_bool")]
    value: bool
};

Как мне написать идиоматические тесты для него?

...