A7 · JSON Structure: object, array: JSON is data as a **system of nested boxes**: an **object** `{}` is a labeled box (key→value), an **array** `[]` is an ordered shelf (same-typ
JSON is data as a **system of nested boxes**: an **object** `{}` is a labeled box (key→value), an **array** `[]` is an ordered shelf (same-type boxes side by side), a **nested** structure is a box inside a box, and there are two sneaky states — `null` (the box exists but is empty) vs a **missing field** (the box isn't there at all). But aren't `null` and "field missing" the same, don't both mean "no value"? No, and this difference is where a tester errs most: `"reporter": null` is the server saying "I intentionally left it empty"; the field being entirely absent may mean "I forgot/removed this field" — one is data, the other is a contract break. In Java the equivalent is `Optional reporter = Optional.empty()` (null, deliberately empty) vs the field not existing in the DTO at all (silently skipped in deserialization). The QA crux: a check like `if (bug.reporter)` returns false for both `null` and "missing", but a contract test must DISTINGUISH them — because "field returned null" is a data state, while "field vanished entirely" is an API regression.
The JSON Anatomy of a Bug Record
🎬 null or Missing? The Silent Disappearance of a Field
Two different responses: one has `reporter: null`, the other has NO reporter field at all. To the eye both look "empty".
A weak test writes `if (bug.reporter)`. This check returns false in BOTH cases — so it CANNOT tell them apart.
The result — if the field silently vanishes one day (an API regression), this weak test still passes green. The bug goes unnoticed.
A strong contract test instead asks separately "does the reporter KEY exist?" — null is a data state, "key missing" is a regression.
The lesson — null ("present but empty") differs from a missing field ("not there at all"). Contract tests separately verify the key's EXISTENCE.
Safely Accessing Nested Data
assignee is an object…
To reach bug.assignee.name, first ensure assignee exists; if assignee is null this access blows up.
null nested = crash…
Reading .name while assignee is null throws "cannot read property of null" — the JS counterpart of Java's NullPointerException.