Using eventually in an AsyncWordSpec

This is my second post regarding the use of eventually in an AsyncWordSpec. The previous post was about using futures in an eventually block in an AsyncWordSpec. This one deals with how to use eventually in an AsyncWordSpec when you don’t use a future. The way to use eventually is this case applies to ScalaTest 3.10, and is possibly also necessarily for other versions.

Suppose you have the following method

def determineValue: Int = {
....
}

that you want to test and this method will after a while return the desired value 1. In an AnyWordSpec, you would test it in the following way:

class TestSpec extends AnyWordSpec with Eventually with Matchers {
  "determineValue" should {
    "return the correct value" in {
      eventually {
        determineValue shouldBe 1
      }
    }
  }
}

Suppose you’re using an AsyncWordSpec, perhaps because other methods of the class you’re testing return futures, then the following code will call determineValue only once:

class TestSpec extends AsyncWordSpec with Eventually with Matchers {
  "determineValue" should {
    "return the correct value" in {
      eventually {
        determineValue shouldBe 1
      }
    }
  }
}

You’ll also see this from the output of the test: normally when using eventually you see the number of times the method method was tested and the last result of the test when the test fails. In this case not. The fix is simple: wrap the eventually block in a Future.successful:

class TestSpec extends AsyncWordSpec with Eventually with Matchers {
  "determineValue" should {
    "return the correct value" in {
      Future.successful {
        eventually {
          determineValue shouldBe 1
        }
      }
    }
  }
}

When the test fails, you will now see that the test is retried multiple times.

Leave a Reply

Your email address will not be published. Required fields are marked *