ReactiveX / RxScala

RxScala – Reactive Extensions for Scala – a library for composing asynchronous and event-based programs using observable sequences

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Observers constructor for tests

hermanbanken opened this issue · comments

Looking at examples/src/test/scala/rx/lang/scala/examples/TestSchedulerExample.scala I figured I could create my Observer like this:

val observer = mock(classOf[rx.Observer[Long]])
val obs: rx.lang.scala.Observer = Observer(new rx.observers.TestObserver(observer))

But it seems that this is not the case as this apply method is private.

Are we supposed to not write tests? Or am I missing something?

PS: The documentation for TestScheduler published at reactivex.io shows the same example, which uses more unknown things like inOrder with a single argument. If I take an up to date Mockito version, this method does have multiple arguments... would be helpful to either fix this or document the version.

The apply methods to go from Java to Scala are private because we want to be able to change them without breaking users' code. The conversion methods that you should use for this are in JavaConversions. So you can either write

val sub = o.subscribe(JavaConversions.toScalaObserver(new TestObserver(observer)))

or you can

import rx.lang.scala.JavaConversions._

and then the conversion is inserted automatically by the compiler.

Regarding mockito and inOrder, you can see what mockito version we use here. So you just have to pick the same version, and it will work.

This should solve the problems you described. Thanks for bringing this up, because it points out several issues in RxScala:

  • Example in TestScheduler scaladoc is out of sync with the code in TestSchedulerExample.
  • Putting examples in the package rx.lang.scala is problematic because they get access to private members, so they can do things that users cannot do.
  • We should update the mockito version.

We'll look into fixing them.

Can anyone can put their own code in rx.lang.scala, even when separately compiled?

Can anyone can put their own code in rx.lang.scala, even when separately compiled?

Yes. But it's a convention that the user should not access package private APIs like this. package private means it's not a public API and will be changed at any time.

It was a retorical question; I actively ignore conventions ;-) The point I was really trying to make that if something is useful in an example, it is probably useful if it private or not. Which why I tend to make as few things private as possible (especially since it is often impossible to really prevent people from accessing it).

@headinthebox I already had this workaround in place:

package rx.lang.scala

/**
 * The apply method for a rx.Observer is hidden in private package scope.
 * Luckily we can create something in that package as well.
 */
object TestUtils {
  def observableFromJs[T](obs: rx.Observer[T]): rx.lang.scala.Observer[T] = Observer.apply(obs)
}

@samuelgruetter, I made a pull request for this, see #168