How to Scrub Non-Deterministic Output

Scrubbers

This page assumes that you understand the concept of Scrubbers.

Lambda example

using namespace ApprovalTests;
Approvals::verify(
    "1 2 3 4 5 6",
    Options().withScrubber(
        [](const std::string& t) {return StringUtils::replaceAll(t, "3", "Fizz");}
    ));

(See snippet source)

This would produce:

1 2 Fizz 4 5 6

(See snippet source)

(In the real world, scrubbers are generally used to remove text that is expected to differ between test runs… Here, we use a trivial example for ease of explanation.)

Pre-made Scrubbers

Regular Expressions (regex)

API for scrubbing with regex

Approval Tests provides lots of convenience methods to scrub text based on regular expressions.

Using a regex search term

For example, here is an example where random numbers are scrubbed:

using namespace ApprovalTests;
std::stringstream os;
os << "Hello " << random(1000) << " World";
Approvals::verify(os.str(),
                  Options(Scrubbers::createRegexScrubber(R"(\d+)", "[number]")));

(See snippet source)

This will produce:

Hello number World

(See snippet source)

Note: In the above example, the caller passes in a std::string, and for convenience of the calling code, Approval Tests converts that to a std::regex. The calling code is responsible for making sure that the string contains a valid regular expression.

Using a lambda for greater control of replacement text

There are many combinations of these parameters, that allow for customization at whatever level you need, the most complex being:

auto input = "1) Hello 1234 World";
auto scrubber = ApprovalTests::Scrubbers::createRegexScrubber(
    std::regex(R"(\d+)"), [](const auto& match) {
        auto match_text = match.str();
        auto match_integer = std::stoi(match_text);
        if (match_integer < 10)
        {
            return match_text;
        }
        else
        {
            return std::string("[number]");
        }
    });

(See snippet source)

This will produce:

1) Hello [number] World

(See snippet source)

GUID

You can scrub GUIDs by using a pointer to the function Scrubbers::scrubGuid.

For example the following code:

using namespace ApprovalTests;
std::string jsonFromRestCall = R"(
    {
        child: {
            id: b34b4da8-090e-49d8-bd35-7e79f633a2ea
            parent1: 2fd78d4a-ad49-447d-96a8-deda585a9aa5
            parent2: 05f77de3-3790-4d45-b045-def96c9cd371
        }
        person: {
            name: mom
            id: 2fd78d4a-ad49-447d-96a8-deda585a9aa5
        }
        person: {
            name: dad
            id: 05f77de3-3790-4d45-b045-def96c9cd371
        }
    }
    )";
Approvals::verify(jsonFromRestCall, Options().withScrubber(Scrubbers::scrubGuid));

(See snippet source)

will produce:

{
            child: {
                id: guid_1
                parent1: guid_2
                parent2: guid_3
            }
            person: {
                name: mom
                id: guid_2
            }
            person: {
                name: dad
                id: guid_3
            }
        }

(See snippet source)

Notice that when GUIDs are repeated within the same file, they are replaced with the same text.