Unit Testing & MockK Flashcards
TESTING › Unit
- What is the difference between a local unit test and an instrumented test on Android?
- A local unit test runs on the JVM of your development machine (src/test, fast, no device) while an instrumented test runs on a real or emulated Android device (src/androidTest) so it can use the real framework. Unit tests are smaller, faster, and more numerous.
- In MockK, what does a relaxed mock do and when would you use one?
- A relaxed mock (mockk(relaxed = true) or @RelaxedMockK) returns sensible default values (0, empty string, empty collection, another mock) for any unstubbed call instead of throwing. Use it to avoid stubbing every method when you only care about a few; relaxUnitFun = true relaxes only Unit-returning functions.
- How do you stub and verify a suspend function with MockK?
- Use the coroutine variants: coEvery { repo.fetch() } returns data to stub, and coVerify { repo.fetch() } to verify. Run the test inside runTest so suspend calls execute synchronously on the test dispatcher.
- What is the difference between a fake and a mock, and which does Google recommend?
- A fake is a real, hand-written lightweight implementation of an interface (e.g. an in-memory repository) with working behavior. A mock is a generated object configured to return canned values and verify interactions. Google recommends preferring fakes for collaborators you own because they are less brittle and test behavior, not call patterns.
- How do you capture an argument passed to a mock in MockK and assert on it?
- Create a slot: val s = slot<User>(), wire it with every { dao.insert(capture(s)) } returns Unit, invoke the code, then assert on s.captured. For multiple invocations use a mutableListOf and capture(list) to collect every value.
- What is the difference between verifyOrder and verifySequence in MockK?
- verifyOrder checks the listed calls happened in that relative order but allows other calls in between. verifySequence is strict: those exact calls, in that order, with no other calls on the mock. verifyAll checks all listed calls happened in any order with nothing else.
- What should you generally NOT write unit tests for, and why?
- Avoid unit-testing framework code (Activities, the OS, the Android SDK), trivial getters/setters, and pure data classes with no logic. They have no meaningful behavior of yours to verify and tests just duplicate the implementation; cover that surface with instrumented or integration tests instead.
- How does dependency injection make a class unit-testable?
- By passing collaborators in (via constructor) behind interfaces instead of constructing them internally, you can substitute fakes or mocks in tests. This removes hard dependencies on Android Context, network, or singletons, letting you run pure JVM tests and exercise edge cases deterministically.
- What does spyk give you that mockk does not?
- spyk wraps a real object so unstubbed methods call the actual implementation, while you can still stub or verify specific methods. A plain mockk has no real behavior at all. Spies are useful for partial mocking but are considered a code smell if overused.