- Interface
- Configuring Scrubbers
- Guid Scrubbing
- RegEx Scrubbing
- Date Scrubbing
- Scrubbing multiple parts of a string
- Using templates
If you are having trouble getting tests running reproducibly, you might need to use a “scrubber” to convert the non-deterministic text to something stable.
Fundamentally, a scrubber is function that takes a string and returns a string. You can create ones by passing in a function or a lambda. We also have some pre-made ones for your convenience.
You can configure all of the Approvals.verify
methods to use scrubbers via the Options
parameter.
For example:
Approvals.verifyAll("guids", guids, new Options(Scrubbers::scrubGuid));
Let's say you have the following Guids in your output:
String[] guids = {"2fd78d4a-ad49-447d-96a8-deda585a9aa5",
"2fd78d4a-1111-1111-1111-deda585a9aa5",
"2fd78d4a-3333-3333-3333-deda585a9aa5",
"2fd78d4a-ad49-447d-96a8-deda585a9aa5",
"2fd78d4a-ad49-447d-96a8-deda585a9aa5 and text"};
You can make this output deterministic by using a scrubber in the options. For example:
Approvals.verifyAll("guids", guids, new Options(Scrubbers::scrubGuid));
This will result in the following .approved.txt
file
guids[0] = guid_1
guids[1] = guid_2
guids[2] = guid_3
guids[3] = guid_1
guids[4] = guid_1 and text
Note: If a Guid is used in multiple places, it will be scrubbed using the same replacement.
That is why you see guid_1
three times.
Using a regex search term
For example, here is an example where random numbers are scrubbed:
String input = "Hello " + new Random().nextInt(100) + " World!";
Approvals.verify(input, new Options(new RegExScrubber("(\\d+)", "[number]")));
producing
Hello [number] World!
The easiest way to scrub a date is by calling
Approvals.verify("created at 03:14:15", new Options().withScrubber(DateScrubber.getScrubberFor("00:00:00")));
which will produce
created at [Date1]
Example Date | RegEx Pattern |
---|---|
Tue May 13 16:30:00 | [a-zA-Z]{3} [a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} |
Wed Nov 17 22:28:33 EET 2021 | [a-zA-Z]{3} [a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} [a-zA-Z]{3,4} \d{4} |
Wed, 21 Oct 2015 07:28:00 GMT | (Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT |
Tue May 13 2014 23:30:00.789 | [a-zA-Z]{3} [a-zA-Z]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2}.\d{3} |
Tue May 13 16:30:00 -0800 2014 | [a-zA-Z]{3} [a-zA-Z]{3} \d{2} \d{2}:\d{2}:\d{2} -\d{4} \d{4} |
13 May 2014 23:50:49,999 | \d{2} [a-zA-Z]{3} \d{4} \d{2}:\d{2}:\d{2},\d{3} |
Oct 13 15:29 | [A-Za-z]{3} \d{2} \d{2}:\d{2} |
May 13, 2014 11:30:00 PM PST | [a-zA-Z]{3} \d{2}, \d{4} \d{2}:\d{2}:\d{2} [a-zA-Z]{2} [a-zA-Z]{3} |
23:30:00 | \d{2}:\d{2}:\d{2} |
2014/05/13 16:30:59.786 | \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}(.\d{3})? |
2020-9-10T08:07Z | \d{4}-\d{1,2}-\d{1,2}T\d{1,2}:\d{2}Z |
2020-09-10T08:07:89Z | \d{4}-\d{1,2}-\d{1,2}T\d{1,2}:\d{2}:\d{2}Z |
2020-09-10T01:23:45.678Z | \d{4}-\d{1,2}-\d{1,2}T\d{1,2}:\d{2}:\d{2}.\d{3}Z |
20210505T091112Z | \d{8}T\d{6}Z |
2024-12-17 | \d{4}-\d{2}-\d{2} |
2024-12-18T14:04:46.746130Z | \d{4}-\d{1,2}-\d{1,2}T\d{1,2}:\d{2}:\d{2}(.\d{1,9})?Z |
13/05/2014 23:50:49 | \d{2}[-/.]\d{2}[-/.]\d{4}\s\d{2}:\d{2}(:\d{2})?( (?:pm|am|PM|AM))? |
If you need to do scrubbing of multiple things, the easiest way is to create multiple scrubbers and then combine them.
final Scrubber portScrubber = new RegExScrubber(":\\d+/", ":[port]/");
final Scrubber dateScrubber = DateScrubber.getScrubberFor("20210505T091112Z");
final Scrubber signatureScrubber = new RegExScrubber("Signature=.+", "Signature=[signature]");
Scrubber scrubber = Scrubbers.scrubAll(portScrubber, dateScrubber, signatureScrubber);
Approvals.verify("http://127.0.0.1:55079/foo/bar?Date=20210505T091112Z&Signature=4a7dd6f09c1e",
new Options(scrubber));
will result in
http://127.0.0.1:[port]/foo/bar?Date=[Date1]&Signature=[signature]
Scrubbers.Templates
contains many templates that can be inlined.