Redactions

Cargo Feature: redactions

For all snapshots created based on serde::Serialize output insta supports redactions. This permits replacing values with hardcoded other values to make snapshots stable when otherwise random or otherwise changing values are involved. Redactions are an optional feature and can be enabled with the redactions feature.

For "readacting" strings you can use the filters feature instead.

Redactions can be defined as the third argument to those assertion macros by using the following syntax:

insta::assert_yaml_snapshot!(..., {
    "selector" => replacement_value
});

They can also be configured via settings.

Selectors

The following selectors exist:

Static Redactions

This is an example of simple static assertions:

#[derive(Serialize)]
pub struct User {
    id: Uuid,
    username: String,
    extra: HashMap<String, String>,
}

insta::assert_yaml_snapshot!(&User {
    id: Uuid::new_v4(),
    username: "john_doe".to_string(),
    extra: {
        let mut map = HashMap::new();
        map.insert("ssn".to_string(), "123-123-123".to_string());
        map
    },
}, {
    ".id" => "[uuid]",
    ".extra.ssn" => "[ssn]"
});

Dynamic Redactions

It's also possible to execute a callback that can produce a new value instead of hardcoding a replacement value by using the dynamic_redaction function. This function can also be used to assert that a value follows a specific format before redaction:

insta::assert_yaml_snapshot!(&User {
    id: Uuid::new_v4(),
    username: "john_doe".to_string(),
}, {
    ".id" => insta::dynamic_redaction(|value, _path| {
        // assert that the value looks like a uuid here
        assert_eq!(value
            .as_str()
            .unwrap()
            .chars()
            .filter(|&c| c == '-')
            .count(),
            4
        );
        "[uuid]"
    }),
});

The two arguments to the callback are of type Content and ContentPath. You can find more information in the API documentation about how they work.

Sorted Redactions

A special feature of the redaction support is the ability to sort a map or sequence at a selector. This is particularly useful if you're working with a HashSet or something similar that has non deterministic serialization order but you need to assert on it. As serde does not let insta distinguish between a vector and a set, no automatic ordering can be provided without causing issues for the general case.

For sorted redactions you can use the sorted_redaction function:

use std::collections::HashSet;
use serde::Serialize;

#[derive(Debug, Serialize)]
pub struct User {
    id: u64,
    username: String,
    flags: HashSet<String>,
}

insta::assert_json_snapshot!(
    &User {
        id: 122,
        username: "jason_doe".to_string(),
        flags: vec!["zzz".into(), "foo".into(), "aha".into(), "is_admin".into()]
            .into_iter()
            .collect(),
    },
    {
        ".flags" => insta::sorted_redaction()
    }
);

Rounded Redactions

For floating point values it can be useful to round them to certain number of decimal places. For this you can use the rounded_redaction function:

use serde::Serialize;

#[derive(Debug, Serialize)]
pub struct Point {
    x: f64,
    y: f64,
}

insta::assert_json_snapshot!(
    &Point { x: 0.4223214, y: 0.424124 }
    {
        ".*" => insta::rounded_redaction(3)
    }
);
Found an issue? You can edit this page on GitHub.