Skip to content

Instantly share code, notes, and snippets.

@realdadfish
Last active September 21, 2018 07:47
Show Gist options
  • Select an option

  • Save realdadfish/8683af83d258e75378294a82f2a3963e to your computer and use it in GitHub Desktop.

Select an option

Save realdadfish/8683af83d258e75378294a82f2a3963e to your computer and use it in GitHub Desktop.
Testing actual subscriptions
package com.xing.android.test.rules.subscription
class MissingSubscriptionToMethodException : Exception()
package com.example.test.rules.subscription
import io.reactivex.Completable
import io.reactivex.Maybe
import io.reactivex.Single
import org.junit.rules.ExternalResource
import java.util.concurrent.atomic.AtomicInteger
class SubscriptionRule : ExternalResource() {
private val subscriptionsList = arrayListOf<SubscriptionTracker>()
override fun after() {
subscriptionsList.forEach { it.verify() }
subscriptionsList.clear()
}
fun <T> trackEmptyMaybe(): Maybe<T> = createTracker(Once).trackEmptyMaybe()
fun <T> trackMaybe(value: T, times: Times = Once): Maybe<T> = createTracker(times).trackMaybe(value)
fun <T> trackNeverMaybe(): Maybe<T> = createTracker(Never).trackNeverMaybe()
fun <T> trackSingle(value: T, times: Times = Once): Single<T> = createTracker(times).trackSingle(value)
fun <T> trackNeverSingle(): Single<T> = createTracker(Never).trackNeverSingle()
fun <T> trackErrorSingle(error: Exception): Single<T> = createTracker(Once).trackErrorSingle(error)
fun trackCompletable(times: Times = Once): Completable = createTracker(times).trackCompletable()
fun trackNeverCompletable(): Completable = createTracker(Never).trackCompletable()
fun trackErrorCompletable(error: Exception): Completable = createTracker(Once).trackErrorCompletable(error)
private fun createTracker(verification: Verification): SubscriptionTracker {
val trace = MissingSubscriptionToMethodException().getStackTraceAsString()
val subscription = SubscriptionTracker(verification, trace)
subscriptionsList.add(subscription)
return subscription
}
private class SubscriptionTracker(val verification: Verification,
val currentStackTrace: String) {
val subscriptionCount = AtomicInteger(0)
fun trackCompletable(): Completable =
Completable.complete().doOnSubscribe {
subscriptionCount.incrementAndGet()
}
fun trackErrorCompletable(error: Exception): Completable =
Completable.error(error).doOnSubscribe {
subscriptionCount.incrementAndGet()
}
fun <T> trackMaybe(value: T): Maybe<T> = Maybe.just(value).doOnSubscribe { subscriptionCount.incrementAndGet() }
fun <T> trackEmptyMaybe(): Maybe<T> = Maybe.empty<T>().doOnSubscribe { subscriptionCount.incrementAndGet() }
fun <T> trackNeverMaybe(): Maybe<T> = Maybe.defer<T> { throw AssertionError("Should never subscribe") }
fun <T> trackErrorSingle(error: Exception): Single<T> =
Single.error<T>(error).doOnSubscribe { subscriptionCount.incrementAndGet() }
fun <T> trackNeverSingle(): Single<T> = Single.defer<T> { throw AssertionError("Should never subscribe") }
fun <T> trackSingle(value: T): Single<T> = Single.just(value).doOnSubscribe { subscriptionCount.incrementAndGet() }
fun verify() {
verification.verify(subscriptionCount.get(), currentStackTrace)
}
}
private fun Throwable.getStackTraceAsString(): String {
val stringWriter = StringWriter()
val printWriter = PrintWriter(stringWriter, true)
this.printStackTrace(printWriter)
return stringWriter.buffer.toString()
}
}
package com.example.test.rules.subscription
open class Times(val expected: Int) : Verification {
override fun verify(subscriptionCount: Int, currentStackTrace: String) {
if (subscriptionCount != expected) {
throw AssertionError("Expected $expected subscriptions, but got $subscriptionCount." +
" Please check that stubbing is correct for the method and if it is called: \n" +
currentStackTrace)
}
}
}
object Never : Times(0)
object Once : Times(1)
package com.example.test.rules.subscription
interface Verification {
fun verify(subscriptionCount: Int, currentStackTrace: String)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment