ScalaTest AsyncFunSuiteLike multiple asserts
Asked Answered
D

1

5

I am rewriting tests that used to test an Akka actor that responded with a String, right now, we use a function that returns a Future[String]. So rewriting the tests using AsyncFunSuiteLike.

Currently I'm looking at a test that has to assert multiple Futures, but I don't seem to understand how to achieve it with AsyncFunSuiteLike.

My test looks as follows:

test("Error responses") {

    NanoHTTPD.Response.Status.values().filter(status => status.getRequestStatus >= 400).map {
      status => {
        val statusCode = status.getRequestStatus
        httpService.setStatusCode(status)
        val responseBody = s"Request failed with status $status"
        httpService.setResponseContent(responseBody)
        val errorMessage = s"Error response (${status.getRequestStatus}): $responseBody"

        myobject.request("123456").map {
          resp => assert(resp === "....")
        }
      }
    }

}

But I am getting an error type missmatch. Expected: Future[Assertion] actual: List[Future[scalatest.Assertion]]

Any idea on how can I achieve multiple assertions within a single test like that?

Derange answered 4/10, 2018 at 20:59 Comment(0)
W
12

ScalaTest asynchronous testing expects the test body to return Future[Assertion]. Now your test body returns List[Future[Assertion]]] because

NanoHTTPD.Response.Status.values() ... // Returns List
  ...
    myobject.request("123456").map(resp => assert(resp === "....")} // Returns Future[Assertion]
  ...
}

We can convert List[Future[T]] to Future[List[T]] using

Future.sequence(listOfFutures)

and, we can convert List[Assertion] to Assertion using

assert(listOfAssertions.forall(_ == Succeeded))

Putting this together we get

Future.sequence {
  NanoHTTPD.Response.Status.values().filter(status => status.getRequestStatus >= 400).map {
    status => {
      val statusCode = status.getRequestStatus
      httpService.setStatusCode(status)
      val responseBody = s"Request failed with status $status"
      httpService.setResponseContent(responseBody)
      val errorMessage = s"Error response (${status.getRequestStatus}): $responseBody"

      myobject.request("123456").map {
        resp => assert(resp === "....")
      }
    }
  }
}.map(listOfAssertions => assert(listOfAssertions.forall(_ == Succeeded)))
Winter answered 5/10, 2018 at 0:27 Comment(1)
Thanks Mario. I am facing an issue tho. When asserting, the errorMessages set on the val do not match the ones in the resp. I am guessing this is due to the asynchronous of the test. I always get the last errorMessage in the resp, since when the async test runs, the NanoHTTPD is always set to the last values set. Is there any way to solve this? (without using Await)Derange

© 2022 - 2024 — McMap. All rights reserved.