Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Android view events for tests
import com.jakewharton.rxrelay2.PublishRelay
import io.reactivex.Observable
import io.reactivex.Observer
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
* [PublishRelay]-like [Observable] enforcing:
* 1. a unique observer at a time, and
* 2. that subscription happens on the main thread.
* In Android views, we bind our events with [RxBinding](
* RxBinding enforces the two above listed conditions; but we lose those enforcement when doing
* testing in our abstracted JVM tests. [AndroidViewEvent] would allow unit tests to fail if a
* presenter violates any of the conditions `RxBinding` enforces.
class AndroidViewEvent<VE : Any> private constructor() : Observable<VE>(), TestRule {
private val events = PublishRelay.create<VE>()
private var mainThreadId = -1L
private var subscribed = false
fun accept(viewEvent: VE) {
override fun subscribeActual(observer: Observer<in VE>) {
// Check main thread.
check(Thread.currentThread().id == mainThreadId)
check(!subscribed) { "Already subscribed to." }
subscribed = true
override fun apply(
base: Statement,
description: Description
): Statement {
return object : Statement() {
override fun evaluate() {
mainThreadId = Thread.currentThread().id
companion object {
fun <VE: Any> create() = AndroidViewEvent<VE>()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment