Explain integration tests and isolate Room DAO tests

Tests integration vs unit testing and Room isolation. Outline: verify real DAO-to-DB interaction with Room.inMemoryDatabaseBuilder; reset state by closing and recreating the DB in @After. Red flag: mocking the DAO or using an on-disk database.
What's really being asked
This question probes three senior-level competencies. First, do you understand the boundary between unit tests, which validate logic in isolation with mocked dependencies, and integration tests, which exercise real component interaction? Second, do you know Room's specific testing affordances, particularly the in-memory database builder and the requirement for an Android environment? Third, do you treat test data as mutable shared state that must be reset to guarantee hermetic, order-independent test execution?
The full answer
Four specific elements in order. First, define the purpose of an integration test as verifying that the DAO, Room, and SQLite actually work together to persist and query data correctly, catching issues like type converter mismatches or migration bugs that unit tests miss. Second, state that you use Room.inMemoryDatabaseBuilder to create a non-persistent database that lives only for the test process, avoiding disk I/O side effects and simplifying cleanup. Third, note that these tests run on an Android environment, either on an emulator or device using AndroidJUnit4, or on the JVM with Robolectric, because Room needs the Android SQLite stack. Fourth, explain isolation by closing the database and recreating it in an @After method, or by using a fresh database instance per test, ensuring that inserts from one test never leak into another.
The mistakes people make
Three red flags stand out. One, suggesting you mock the DAO or the database entirely, which collapses the integration test back into a unit test and defeats the purpose. Two, using a persistent on-disk database file without cleanup, which creates flaky ordering dependencies between tests. Three, proposing to manually delete rows with DAO methods instead of destroying the database instance, which is slower, riskier, and can fail if foreign key constraints or triggers are involved.
What usually comes next
An interviewer might push on migration testing, asking how you would verify that a schema change does not lose user data. They could ask about testing with a Provider or Repository pattern, where you must decide whether to test the DAO directly or through the abstraction layer. They might also ask how to handle coroutines or RxJava streams in these tests, expecting you to use runTest or InstantTaskExecutorRule to make asynchronous Room operations synchronous for deterministic assertions.
A concrete example
Suppose you have a UserDao with an insert and a getUserById method. In your test class annotated with @HiltAndroidTest or @RunWith AndroidJUnit4 class, you declare a private lateinit var db AppDatabase. In @Before, you initialize it with Room.inMemoryDatabaseBuilder ApplicationProvider.getApplicationContext AppDatabase::class.java build, and you obtain the DAO with db.userDao. In @After, you call db.close. Each test then creates its own seed data, calls the DAO methods, and asserts against the returned objects. Because the database is in memory and recreated for every test, test A inserting a user with ID one cannot interfere with test B asserting that ID one does not exist.
Interview question
Which setup best ensures hermetic, order-independent Room DAO integration tests that exercise real database behavior?
- a.Use a persistent on-disk database and delete rows manually via DAO methods after each test
- b.Use Room.inMemoryDatabaseBuilder to create a fresh database per test and close it in @AfterCorrect
- c.Run the tests on the JVM using a standard JUnit runner without an Android environment
- d.Mock the DAO with Mockito and verify interactions with a fake database
Why? this is the answer
Using Room.inMemoryDatabaseBuilder and closing the database in @After guarantees a clean slate for every test while still exercising real SQLite interaction. Relying on an on-disk database with manual row deletion is risky because leftover data or foreign key constraints can create flaky, order-dependent failures.
Just read this? Test yourself on what you have been reading.
Read the original → developer.android.com
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on android — each one lists the topics its interview covers.
See open roles