Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chain different return in Mockito for retryWhen call

I'm creating unit tests for my RxJava observables in Android.

I want to chain return values from a mock and simulate error/resume values in a observable.

I'm doing this:

when(repository.getObservable())
            .thenReturn(Observable.error(new Exception()))
            .thenReturn(Observable.just(driver));

My observable:

return repository.getObservable()
            .retryWhen(observale -> {
                 return observable
                        .zipWith(Observable.range(1, 3), Pair::create)
                        .flatMap(o -> {
                             if (o.second < count) {
                               return Observable.timer(1000, TimeUnit.MILLISECONDS);
                             }
                             return Observable.error(o.first);
            })))

But I only receive the Observable.error(new Exception()), even calling the retryWhen method 3+ times.

Did somebody know how can I test the re-emission of a different observable to test the retryWhen operator?

like image 772
Deividi Cavarzan Avatar asked Apr 14 '16 00:04

Deividi Cavarzan


People also ask

Can we mock same method twice?

We can stub a method with multiple return values for the consecutive calls.

What does @mock do in Mockito?

Mockito @Mock Annotation We can mock an object using @Mock annotation too. It's useful when we want to use the mocked object at multiple places because we avoid calling mock() method multiple times. The code becomes more readable and we can specify mock object name that will be useful in case of errors.

What is thenReturn in Mockito?

thenReturn or doReturn() are used to specify a value to be returned upon method invocation. //”when this method is called, then do something” when(passwordEncoder.encode("1")).thenReturn("a"); or. //”do something when this mock's method is called with the following arguments” doReturn("a").

What does stubbing mean in Mockito?

A stub is a fake class that comes with preprogrammed return values. It's injected into the class under test to give you absolute control over what's being tested as input. A typical stub is a database connection that allows you to mimic any scenario without having a real database.


1 Answers

retryWhen() won't call repository.getObservable() a second time. Instead, it takes the Observable.error() that was returned the first time and resubscribes to it.

In order to use retryWhen() in this way, you'd have to return a single Observable that returns an error the first time it's subscribed to and does not do so in subsequent subscriptions. For example, you could do something like this:

Observable.defer(new Func0<Observable<String>>() {
  boolean hasBeenSubscribedTo = false;

  @Override public Observable<String> call() {
    if (!hasBeenSubscribedTo) {
      hasBeenSubscribedTo = true;
      return Observable.error(new Exception());
    }
    return Observable.just("Hello, world!");
  }
})
.retryWhen(/* ...etc... */)
like image 140
Dan Lew Avatar answered Oct 02 '22 14:10

Dan Lew