test: fix NotificationsRepositoryTest (android.util.Log not mocked) #29

Merged
starsetbyte merged 3 commits from fix/notifications-test-android-log into main 2026-06-21 12:32:21 +00:00
Owner

Problem

NotificationsRepositoryTest > markAllSeen still marks local rows read when server call throws has been failing on main:

java.lang.RuntimeException: Method w in android.util.Log not mocked.
    at android.util.Log.w(Log.java)
    at NotificationsRepository.markAllSeen(NotificationsRepository.kt:102)

When updateSeen throws, markAllSeen's catch block logs via Log.w. In plain JVM unit tests android.jar stubs throw "not mocked", so the log call itself throws and fails the assertion. The other test passes only because it never enters the catch block.

This is a test-environment issue, not a production bugmarkAllRead() runs before the server call, so the optimistic local update is correct.

Fix

Enable testOptions.unitTests.isReturnDefaultValues = true so unmocked android.jar methods return defaults instead of throwing — the approach the "not mocked" error message itself links to. No production code changes; no Robolectric.

Tradeoff: this is a global unit-test setting, so unmocked android stubs across all tests now return defaults rather than throwing. That's the conventional Android setup and the full unit suite stays green.

Verification

./gradlew :app:testDebugUnitTest — BUILD SUCCESSFUL (previously 1 failing).

🤖 Generated with Claude Code

https://claude.ai/code/session_0151pbAku7AeA9fgzWKVQLPE

## Problem `NotificationsRepositoryTest > markAllSeen still marks local rows read when server call throws` has been failing on `main`: ``` java.lang.RuntimeException: Method w in android.util.Log not mocked. at android.util.Log.w(Log.java) at NotificationsRepository.markAllSeen(NotificationsRepository.kt:102) ``` When `updateSeen` throws, `markAllSeen`'s catch block logs via `Log.w`. In plain JVM unit tests android.jar stubs throw "not mocked", so the log call itself throws and fails the assertion. The other test passes only because it never enters the catch block. **This is a test-environment issue, not a production bug** — `markAllRead()` runs before the server call, so the optimistic local update is correct. ## Fix Enable `testOptions.unitTests.isReturnDefaultValues = true` so unmocked android.jar methods return defaults instead of throwing — the approach the "not mocked" error message itself links to. No production code changes; no Robolectric. Tradeoff: this is a global unit-test setting, so unmocked android stubs across all tests now return defaults rather than throwing. That's the conventional Android setup and the full unit suite stays green. ## Verification `./gradlew :app:testDebugUnitTest` — BUILD SUCCESSFUL (previously 1 failing). 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0151pbAku7AeA9fgzWKVQLPE
test: return default values for android.jar stubs in unit tests
All checks were successful
peregrine-ci / assembleDebug Build succeeded (18s)
6651090e08
`NotificationsRepositoryTest.markAllSeen still marks local rows read when
server call throws` failed because `markAllSeen`'s catch block calls
`android.util.Log.w`, and android.jar stubs throw "Method not mocked" in
plain JVM unit tests. The production code is correct (markAllRead runs
before the server call); only the test environment was at fault.

Enable `testOptions.unitTests.isReturnDefaultValues` so unmocked android.jar
methods return defaults instead of throwing — the approach the "not mocked"
error itself recommends — letting error-path logging be unit-tested without
pulling in Robolectric.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0151pbAku7AeA9fgzWKVQLPE
Merge branch 'main' into fix/notifications-test-android-log
All checks were successful
peregrine-ci / assembleDebug Build succeeded (18s)
68f336d03c
Merge branch 'main' into fix/notifications-test-android-log
All checks were successful
peregrine-ci / assembleDebug Build succeeded (2s)
edd9e18763
Sign in to join this conversation.
No description provided.