Rajeev Akotkar
Rajeev Akotkar

Reputation: 1397

Unit Testing RxJava Flowable using spock

I have below snippet for fetching data from MongoDB using com.mongodb.reactivestreams.client.MongoClient and Flowable

The snippet goes like:

Flowable
  .fromPublisher(
     mongoClient
      .getDatabase(mydb)
      .getCollection(mycollection)
      .find()
      .limit()
  )
  .firstOrError()
  .toMaybe()
  .doOnError(error -> { /* somecode */ })

I tried mocking every step of this fluent expression, e.g.

MongoDatabase someDb = Mock(MongoDatabase)
mongoClient.getDatabase(mydb) >> somedb

but on doing this somehow the test keeps running.

What is the correct way to unit test this using Spock?

Upvotes: 0

Views: 368

Answers (2)

kriegaex
kriegaex

Reputation: 67387

In addition to Leonard's idea, you might also want to look into implementing a special ThisResponse implements IDefaultResponse which always returns the mock instance for every mock method call and using that like Mock(defaultResponse: ThisResponse.INSTANCE) for your fluent API class(es). This works nicely as long as the fluent API methods used in the test are supposed to return this or at least another object of the given type. Only where another type is returned, you need to stub something.

Check this answer for more details. As soon as you update your question with a little MCVE, you may also ask follow-up questions if you have any problems using that solution.


Update 2022-03-08: I re-wrote the linked answer after learning about the special behaviour of EmptyOrDummyResponse for methods returning the mocked type. I am also describing now the related Spock 2 syntactic sugar syntax there.

Upvotes: 0

Leonard Brünings
Leonard Brünings

Reputation: 13242

Fluent interfaces are a PITA to mock, my strategy is to put those calls into a separate class / method and mock that. And then to test the fluent part in an integration test.

Upvotes: 0

Related Questions