0

I have the following unit test:

  test("All - gather message") {
    def fs: List[Future[Int]] = List(Future{
      blocking {Thread.sleep(4000)}
      println("Finished sleeping in future 1!")
      1
    }, Future {
      blocking {Thread.sleep(3000)}
      println("Finished sleeping in future 2!")
      2
    }, Future {
      blocking {Thread.sleep(2000)}
      println("Finished sleeping in future 3!")
      3
    })

    val f: Future[List[Int]] = Future.all(fs)
    f onComplete { case x => {
        println("x is: " + x.get)
        assert(x.get == List(1, 2, 3))
      }
    }
    Await.ready(f, 5 seconds)
  }

This is part of a test suite.

The problem is that when my code doesn't produce the correct result, the test is still passed and the error message appears in the output of the next unit test in the test suite.

I think this is because once f completes, the test function returns, and only after this the code from the onComplete block gets executed.

I would like the test function to return only after the code from onComplete is executed.

How can I do this?

octavian
  • 15,986
  • 38
  • 119
  • 229

1 Answers1

1

The reason your test isn't failing is that your onComplete block is being run in a separate thread from your actual test method. Consider this test:

class MyTest extends FlatSpec {
    it should "get a List" in {
        def fs: List[Future[Int]] = List(Future(1))

        println("Test thread " + Thread.currentThread().getName)

        val f: Future[List[Int]] = Future.sequence(fs)
        f onComplete { case x => {
            println("Complete thread " + Thread.currentThread().getName)
            assert(x.get == List(5))
        }}
        Await.ready(f, Duration.Inf)
   }
}

When run we get this output and the test doesn't fail:

Test thread: ScalaTest-run-running-MyTest
Complete thread: ForkJoinPool-1-worker-11

You want your assertion to be in the same thread as your test. Ultimately I think you're looking for something like this outside of your onComplete:

assert(Await.result(f, 5 seconds) == List(1, 2, 3))
Matt Fowler
  • 1,783
  • 2
  • 13
  • 17