jeudi 14 mars 2019

Testing exception of Async method (Scala - Play)

In an attempt to increase my code's sbtCoverage I am trying to test the Async method listAllProducts for exceptions. My controller method looks like that:

class ProductController @Inject() (cc: ControllerComponents, prService: ProductService)
(implicit ec: ExecutionContext) AbstractController(cc) with I18nSupport {

  def listAllProducts: Action[AnyContent] = Action.async { implicit request =>
    productService.findAll().map {
      listOfProducts           => Ok(views.html.products.list(listOfProducts))
    }.recover {
      case t: TimeoutException => Logger.error("Timed out")
                                  InternalServerError(t.getMessage)
    }
  }

}

My ProductService.findAll method looks like this:

class ProductService {
  def findAll(): Future[List[Product]] = collection.flatMap(
      _.find(baseQuery, projection)
      .cursor[Product](ReadPreference.primary)
      .collect[List](-1, Cursor.FailOnError[List[Product]]())
    )
}

In my ProductSpec.scala file I have the following tests:

class ProductSpec extends PlaySpec with MockitoSugar with Injecting with Results with ScalaFutures {

  "Caling ProductController.listAllProducts" should {

    "throw an exception when the future fails (A)" in {
      val mockProductService = mock[ProductService]
      val c: ProductController = new ProductController(stubControllerComponents(), mockProductService){
        when(mockProductService.findAll()).thenReturn(Future.failed(new TimeoutException("Timed out")))
      }

      whenReady(mockProductService.findAll().failed) { e =>
        intercept[java.lang.Exception] {
          c.listAllProducts().apply(FakeRequest(GET, "/products").withCSRFToken)
        }
      }
    }

    "throw an exception when the future fails (B)" in {
      val mockProductService = mock[ProductService]
      val c: ProductController = new ProductController(stubControllerComponents(), mockProductService){
        when(mockProductService.findAll()).thenReturn(Future.failed(new TimeoutException("Timed out")))
      }

      intercept[java.lang.Exception] {
        c.listAllProducts().apply(FakeRequest(GET, "/products").withCSRFToken)
      }
    }
  }
}

Both tests fail with the message Expected exception java.lang.Exception to be thrown, but no exception was thrown

Can anyone please help with these tests? Thank you in advance. :)

Aucun commentaire:

Enregistrer un commentaire