How do you assert that dates and amounts in an outbound message are formatted for the recipient?
answer
- Format belongs to the reader, not the host
- The preference is seeded profile data
- Two profiles, one attribute apart
- Pick values a wrong format would change
- Never re-derive the expected string
basics
~20 sAssert against the recipient's declared preference, seeded as profile data, rather than the sending host's default. Choose values a wrong format changes — a day past the twelfth, an amount above a million, a time near midnight in their zone.
solid answer
~50 sSeed a recipient profile that carries a declared region preference and a declared time zone, then assert the relationship between that profile and the rendered text. Two profiles differing in exactly one attribute are the real test: if both messages render identically, the preference never reached the rendering layer. Choose values that **can** fail. The 3rd of April reads the same under both common day-and-month orderings; the 27th does not. An amount of 12.5 shows no group separator; a value above a million does. A time near midnight in the recipient's zone catches an offset error that midday would hide, because the rendered date moves too. Do not build the expected string by calling the product's own formatting routine — that assertion agrees with the product even when the product is wrong. Write a literal, or assert structural properties you state yourself.
code
pseudocode · 13 linesprofiles = [
{ region: REGION_A, zone: ZONE_A, expectedDate: "27.11.2026", expectedTotal: "1 234 567,89" },
{ region: REGION_B, zone: ZONE_B, expectedDate: "11/27/2026", expectedTotal: "1,234,567.89" }
]
for p in profiles:
recipient = seedRecipient(region = p.region, zone = p.zone)
placeOrder(recipient, total = 1234567.89, at = INSTANT_NEAR_MIDNIGHT_IN(p.zone))
body = captureMessageFor(recipient)
assert body contains p.expectedDate // literal, not re-derived
assert body contains p.expectedTotal
assert renderedBodyOf(profiles[0]) != renderedBodyOf(profiles[1])go deeper
Be ready to say that a date, a time and an amount are rendered differently for different readers, and that a message should follow the recipient's declared preference rather than the settings of whatever machine sent it.
Explain how to seed the preference as profile data and how to pick values that discriminate — a day past the twelfth, a number large enough to show a group separator, a time near midnight in the recipient's zone.
Show why re-deriving the expected string with the product's own formatter is a tautology, and offer structural assertions as the maintainable alternative. Be ready to diagnose a message where one value is formatted upstream by a layer the preference never reached.
Own the policy question: which values in outbound content are worth pinning as literals, what the fallback is when a recipient declares nothing, and how the estate avoids a hundred brittle string assertions while still catching a silent default change.
A notification is rendered by a machine in one place and read by a person somewhere else. The date, the time, the amount and the quantity in that message have to be right for the reader: the ordering of day and month, the group and decimal separators, where the currency symbol sits, and which clock a time refers to. What the rendering host happens to be configured with is irrelevant to the reader — and is the single most common source of this defect, because the value looks perfectly correct to everyone whose own machine is configured the same way. ## Two sources of truth, and only one of them counts The case needs a recipient whose preference is **data it seeded deliberately**: a profile carrying a declared region-and-language preference and a declared time zone. The assertion is then about the relationship between that profile and the rendered text — not about the machine that ran the suite. Two cases over two profiles that differ in exactly one attribute — same order, same amount, different declared region — are worth more than twenty cases over a single profile, because the difference between the two rendered bodies *is* the behaviour under test. If both bodies come out identical, the preference never reached the rendering layer, and that is the defect you were looking for. (The suite still pins its own defaults so runs are repeatable. That is a different concern: pinning the runner's defaults makes results stable, it does not make the rendering correct for a recipient.) ## Choose values that can actually fail Half the cases written in this area could never have failed. A value only tests a format when a wrong format changes it. | Value in the message | A choice that hides defects | A choice that discriminates | |---|---|---| | Date | the 3rd of April — identical under both common day/month orderings | the 27th of a month, which is only valid one way round | | Number | `12.5` — no group separator ever appears | a value above a million with a fractional part | | Currency | asserting the symbol is present anywhere | a profile whose convention places the symbol after the number | | Time | midday — a several-hour offset error still looks plausible | a time within an hour of midnight in the recipient's zone | The midnight-adjacent time is the sharpest instrument here: if the offset is applied wrongly, the rendered *date* changes as well, so one assertion catches both the clock and the calendar. ## Do not re-derive the expectation The tempting shortcut is to build the expected string inside the case by calling the same formatting routine the product calls. The assertion then agrees with the product whenever the product is wrong, which is the definition of a tautology — it can only fail if the routine is non-deterministic. Write the expectation instead in one of two honest forms: 1. **A hand-written literal** for the profile you seeded. It is brittle in a useful way: it fails when the rendering changes, and a person reads the diff and decides. 2. **Structural properties stated independently of the product.** The day component appears before the month; the group separator is the character that region uses; the fractional part has exactly two digits; the rendered date equals the day that instant falls on in the recipient's declared zone. The second form survives copy changes and still catches real defects, so it is usually the better default, with a literal reserved for the one or two values that matter most. ## Where this actually breaks in a product - The preference exists on the profile but never reaches the rendering layer, so the host default is used silently. - The preference reaches the template but one value is formatted earlier, upstream, by a layer that never received it — so most of the message is right and one line is not. - The instant is correct and the zone is not, which is invisible for most of the day and wrong near midnight. - A recipient has **no** declared preference. The product has a fallback, and that fallback is a decision rather than an accident: seed a profile with the preference absent, assert what the fallback produces, and a silent change to it fails a case instead of surprising a reader. ## What to say in the room The strong answer has three moves and takes about a minute. First, the recipient's preference is seeded data, so the assertion compares the rendered text against the profile rather than against the host. Second, pick discriminating values, and say why the 27th and a near-midnight time were chosen. Third, refuse to compute the expected string with the product's own formatter, and offer structural assertions as the maintainable alternative. A candidate who adds the missing-preference fallback case is showing they have shipped this rather than read about it.
- Why is asserting a time at midday a weaker case than asserting one near midnight?At midday a wrong offset of a few hours still renders a plausible time on the correct date, so the case passes. Near midnight in the recipient's zone, the same error moves the rendered date as well, so one assertion catches both a clock error and a calendar error.
- The recipient has no declared region preference. What should the case assert?Whatever the product's fallback produces, pinned deliberately. Seed a profile with the preference absent, assert the rendered format explicitly, and the fallback becomes a stated decision rather than an accident. A silent change to it then fails a case instead of surprising a reader.
- Both profiles render identical bodies and both assertions pass. What does that tell you?That the expectations were written too loosely to discriminate, or that the preference never reached the rendering layer and both fell back to the same default. Asserting the two bodies differ is a cheap extra check that turns the second case into a real comparison.
saying these in an interview costs you the question
- Builds the expected string with the product's own formatting routine
- Uses a date whose day is below thirteen
- Asserts a currency symbol is present but never its position
- Assumes the sending host's defaults are the recipient's
- Treats a missing preference as undefined rather than pinning the fallback