Improve Android Testability with Fakes and Factories
Article Summary
Brian Plummer from OkCupid hit a wall adding a simple analytics event: his unit tests broke because static constructs were calling the analytics library directly. Here's how he fixed it with a pattern that made the code more testable.
OkCupid's engineering team faced a common legacy code problem: tightly coupled analytics that broke tests. The existing pattern had ViewModels calling analytics directly through static objects, making unit testing impossible without invoking the actual analytics SDK in the JVM.
Key Takeaways
- Introduced interfaces to decouple ViewModels from concrete analytics implementations
- Created fakes with boolean flags to verify events fired without calling real SDKs
- Extracted processing logic into data class factories for isolated testing
- Reduced ViewModel responsibility by moving event creation to companion objects
By abstracting analytics behind interfaces and using fakes instead of mocks, the team made their ViewModels testable while keeping event processing logic verifiable in isolation.
About This Article
Brian Plummer's ViewModel test failed when he added a new analytics event. The SessionMetrics class was directly instantiating AnalyticsTool.getInstance(), which doesn't work in the JVM test environment.
Plummer created a SessionMetrics interface with a concrete AnalyticsLibSessionMetrics implementation. He then built a FakeSessionMetrics that tracked event invocations without calling the actual analytics library.
The refactored pattern made it possible to test three separate scenarios. The team could validate ViewModel behavior, verify that events fire using boolean flags, and test isolated processing logic through SelectedMessageEvent.from() factory methods.