Search code examples
scalastreamside-effectsfs2

fs2 streams: testing an fs2 server


I have a stream in this form:

val server = for {
  _ <- Stream.eval(initTasks)
  serverBinding <- Stream.eval(...)
} yield serverBinding

I understand that in order to run it, I should do something like:

server
  .compile
  .drain
  .unsafeRunAsync(_ => ())

Now, I want to write unit-tests for this server, but I can only run my tests when the server is all set-up. Currently, in my beforeAll block, I have:

testServer
  .interruptWhen(shutdownSignal)
  .compile
  .drain
  .unsafeRunAsync(_ => ())

Thread.sleep(5000)

and in my afterAll block, I have:

shutdownSignal.set(true).unsafeRunSync()

to bring down the server after my test.

I was wondering if I could use signals to achieve my stated goal so that I can somehow "wait" on the signal so that the tests are run only once the signal is up. Alternatively I'd love to know of the generic/idiomatic way of doing this.


Solution

  • fs2 had this construct called Promise which can be used for this purpose. It's now deprecated but Cat's Deferred can be used. So before running compile.drain on the stream, we can make the stream complete the promise/deferred value and then in the beforeAll we can wait on its value.