How to Scrub Non-Deterministic Output
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.