Unit Testing & MockK Interview Questions
TESTING › Unit
How do you decide what's actually worth unit testing in a ViewModel versus what you'd skip? Walk me through your mental checklist.
What a strong answer covers: Worth testing: business logic, state transformations, branching conditions, edge cases like empty lists or error states, and anything where a regression would silently ship a wrong answer; skip trivial pass-through getters, framework wiring that's just calling a well-tested library method, and UI layout details that belong in a different kind of test. A strong answer also flags that if a ViewModel is hard to unit test because it reaches directly into Android framework classes or does too much in one function, that's itself a design smell worth fixing rather than working around with heavier mocking.
You inherit a test suite that mocks everything, including simple data classes and pure functions, and tests break constantly whenever an unrelated field gets renamed. What's actually gone wrong, and how would you fix the suite's design?
What a strong answer covers: This is classic over-mocking: tests are asserting on implementation details and interaction patterns instead of observable behavior, so they're brittle to refactors that don't change actual behavior, which defeats the point of a safety net. The fix is reserving mocks/verify for real collaborators with side effects (network, database, other objects you don't own), using real objects or hand-written fakes for value types and pure logic, and asserting on outputs and state rather than on exactly which methods got called in what order.
Walk me through how you'd unit-test a use case that combines two upstream Flows with combine and has time-based logic like a debounce. What tools do you reach for, and what's actually hard about testing this correctly?
What a strong answer covers: You'd run it under runTest with a TestDispatcher so virtual time can be advanced deterministically, and typically reach for Turbine to collect emissions from the combined Flow and assert on the sequence, using advanceTimeBy or advanceUntilIdle to move past the debounce window without real delays. The hard part is that combine re-emits whenever either upstream emits, so tests need to control emission timing precisely (emit from one source, advance time, emit from the other) to actually exercise the debounce and race conditions, rather than emitting everything up front and getting a misleadingly clean pass.