1 个不稳定版本

0.1.0 2021年11月20日

#477 in 测试

Download history • Rust 包仓库 29/week @ 2024-03-12 • Rust 包仓库 52/week @ 2024-03-19 • Rust 包仓库 40/week @ 2024-03-26 • Rust 包仓库 40/week @ 2024-04-02 • Rust 包仓库 21/week @ 2024-04-09 • Rust 包仓库 36/week @ 2024-04-16 • Rust 包仓库 54/week @ 2024-04-23 • Rust 包仓库 31/week @ 2024-04-30 • Rust 包仓库 24/week @ 2024-05-07 • Rust 包仓库 56/week @ 2024-05-14 • Rust 包仓库 42/week @ 2024-05-21 • Rust 包仓库 31/week @ 2024-05-28 • Rust 包仓库 23/week @ 2024-06-04 • Rust 包仓库 17/week @ 2024-06-11 • Rust 包仓库 17/week @ 2024-06-18 • Rust 包仓库 22/week @ 2024-06-25 • Rust 包仓库

88 每月下载量
3 crate 中使用

自定义许可协议

40KB
903

assert_json

assert_json提供了一种简单且声明式的方法来测试Rust中的JSON输入。`assert_json` 是一个受 serde json 宏 启发而成的 Rust 宏。它不是从JSON字面量创建JSON值,而是确保JSON输入符合指定的验证规则。

当发生验证错误时,`assert_json` 也会输出美观的错误信息。

如何使用

use assert_json::assert_json;
use assert_json::validators;

#[test]
fn test_json_ok() {
    let json = r#"
        {
            "status": "success",
            "result": {
                "id": 5,
                "name": "charlesvdv"
            }
        }
    "#;

    let name = "charlesvdv";

    assert_json!(json, {
            "status": "success",
            "result": {
                "id": validators::u64(|&v| if v > 0 { Ok(())} else { Err(String::from("id should be greater than 0")) }),
                "name": name,
            }
        }
    );
}

任何变量或表达式都将作为验证规则进行插值,以匹配传递给宏的变量/表达式的类型和值。

现在,如果JSON输入被更改为以下不正确的内容

    let json = r#"
        {
            "status": "success",
            "result": {
                "id": 5,
-                "name": "charlesvdv"
+                "name": "incorrect name"
            }
        }
    "#;

您将得到以下这种易于理解的错误信息

thread 'xxxx' panicked at 'error: Invalid JSON
  ┌─ :4:174"name": "incorrect name"^^^^^^^^^^^^^^^^ Invalid value. Expected "charlesvdv" but got "incorrect name".

自定义验证器

一组验证器已实现在`validators`模块中。如果需要,也可以通过实现`Validator` trait来创建自己的验证过程。

use assert_json::{assert_json, Error, Validator, Value};

fn optional_string(expected: Option<String>) -> impl Validator {
    OptionalStringValidator { expected }
}

/// Matches a null JSON value if expected is None, else check if the strings
/// are equals
struct OptionalStringValidator {
    expected: Option<String>,
}

impl Validator for OptionalStringValidator {
    fn validate<'a>(&self, value: &'a Value) -> Result<(), Error<'a>> {
        if let Some(expected_str) = &self.expected {
            let string_value = value
                .as_str()
                .ok_or_else(|| Error::InvalidType(value, String::from("string")))?;

            if expected_str == string_value {
                Ok(())
            } else {
                Err(Error::InvalidValue(value, expected_str.clone()))
            }
        } else {
            value.as_null()
                .ok_or_else(|| Error::InvalidType(value, String::from("null")))
        }
    }
}

let json = r#"
    {
        "key": "value",
        "none": null
    }
"#;
assert_json!(json, {
    "key": optional_string(Some(String::from("value"))),
    "none": optional_string(None),
});

替代方案

致谢

感谢serde-rs/json项目成员,尤其是那些为`json!宏做出贡献的人。

依赖项

~1.1–9MB
~76K SLoC