Stop hardcoding test responses. Switch mock behavior at runtime — without recompiling.
Optimus wraps Retrofit with a declarative mock layer. Define every possible response your API could return, mark one as the default, and flip between them at runtime from a debug UI or in tests. No more rebuilds to reproduce edge cases.
1. Declare your mock responses
class MockUser : MockResponse {
@Default
val HTTP200 = success { User(id = 1) }
val HTTP401 = error(401, "Unauthorized") { ApiError(401, "Unauthorized") }
val HTTP503 = error(503, "Service Unavailable") {}
}2. Wire it up once
val supplier = MockResponseSupplier.create(sharedPreferences)
val optimus = Optimus.Builder(supplier)
.retrofit(retrofit, sharedPreferences)
.mockGraph(
alter(Api::class.java, "Api") {
Api::login with MockUser::class named "Login"
}
)
.converter(Converter.create(moshi))
.build()3. Use it like a regular Retrofit service
val api = optimus.create(Api::class.java)4. Switch responses at runtime via the debug UI
AlertDialog.Builder(this)
.setView(OptimusView(this).apply { setOptimus(optimus) })
.show()Optimus makes unit and UI tests precise — no network calls, no random failures.
// Set up with an in-memory supplier
val supplier = MockResponseSupplier.memory()
val optimus = Optimus.Builder(supplier).retrofit(retrofit).mockGraph(mockGraph).build()
// Pin the exact response you want to test
mockResponseSupplier.set(Api::login, MockUser::HTTP401)
assertThat(api.login().code()).isEqualTo(401)dependencies {
implementation("com.cocosw:optimus:2.0.0")
}