What makes a good unit test?
Assesses fundamental understanding of Software Testing & QA conventions, runtime behavior, and memory/performance considerations.
Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.
A good unit test is fast, deterministic, isolated and focused on behaviour.
Characteristics:
- Tests one behaviour, with a clear name such as
rejects_negative_amount, so a failure tells you what broke. - Follows Arrange-Act-Assert, keeping setup, action and verification distinct.
- Has no dependence on execution order, shared mutable state, the clock, the network or random values; inject these as dependencies.
- Asserts on observable outcomes rather than internal implementation, so refactoring does not break it.
- Has a single logical assertion concept; multiple asserts are fine if they describe one behaviour.
- Fails with a message that shows expected versus actual.
- Runs in milliseconds, so the suite can run on every save.
@Test void rejectsNegativeAmount() {
assertThrows(IllegalArgumentException.class,
() -> account.deposit(-1));
}
Avoid over-mocking, which couples tests to implementation. A test that never fails, or one that fails for unrelated reasons, costs more than it protects.
Candidate Response Strategy & Interview Tips
- Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
- Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
- Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
- Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.