Testing Architecture — Series 2

Preview — 3 of 10 questions

What distinguishes a Fake from a Stub in the classic test-double taxonomy (Dummy, Fake, Stub, Spy, Mock)?

javascript
// Fake: a working but simplified implementation
class FakeDatabase {
  #data = new Map();
  save(id, value) {
    this.#data.set(id, value);
  }
  find(id) {
    return this.#data.get(id);
  }
}

// Stub: returns hardcoded values, no real logic
const stubPricing = { getPrice: () => 9.99 };
AA Fake can only be used in browser tests; a Stub can only be used in Node.js tests.
BA Fake is a genuinely working, simplified implementation of the real thing (e.g., an in-memory database that actually stores and retrieves data, just not durably) — it has real, if simplified, behavior. A Stub simply returns pre-programmed, hardcoded responses regardless of input, with no real underlying logic at all.
CA Fake always fails intentionally to test error handling; a Stub always succeeds.
DA Fake and a Stub are exactly the same thing; the distinction is purely historical naming.

Kent C. Dodds "Testing Trophy" model reshapes the classic testing pyramid by giving relatively more weight to integration tests, compared to the traditional pyramids large base of granular unit tests. What's the core argument behind this shift?

AThe Testing Trophy argues that unit tests are useless and should never be written at all.
BThe Testing Trophy is identical to the testing pyramid, just drawn upside down for visual variety.
CThe Testing Trophy replaces all automated testing with manual QA exclusively.
DIntegration tests strike a better balance between confidence and cost for many applications: they exercise how multiple real units actually work together (closer to how the software is genuinely used), catching a wider class of real bugs than isolated unit tests, while still running much faster and more reliably than full E2E tests — so investing proportionally more in that middle layer can yield more "confidence per test" than a huge base of narrow, implementation-focused unit tests.

As a codebase accumulates more feature flags, what testing challenge specifically emerges, and what's a common mitigation?

javascript
function renderCheckoutButton(user, flags) {
  if (flags.isEnabled('new-checkout-flow')) {
    return renderNewCheckout(user);
  }
  return renderLegacyCheckout(user);
}
AFeature flags have no effect on testing whatsoever, since they're resolved entirely at build time before any test runs.
BThe only testing challenge with feature flags is remembering to delete the if statement, which has nothing to do with test coverage.
CEvery feature flag effectively doubles the number of meaningfully distinct code paths through the application (flag on vs. off) — with multiple flags, this compounds combinatorially, and testing every possible combination of flag states quickly becomes impractical. Common mitigations include testing each flag's own on/off behavior in isolation (rather than every combination), keeping the number of simultaneously "live" flags small, and removing flags promptly once a feature is fully rolled out or fully reverted.
DFeature flags make combinatorial testing unnecessary, since flags are always mutually exclusive by design.

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.