Testing Scala Play application using Mock and GuiceApplicationBuilder

12 July 2017

In this example the controller class Product Controller fetches data from an external service called DataService. Since we can't call real APIs during Test we need to mock these 3rd Party services and return a fake JSON mock data instead. We use Mockito to return a fake instance and inject it into the application in test using GuiceApplicationBuilder.

Sample Test

import scala.io.Source
import org.junit.runner.RunWith
import org.scalatest.
import org.scalatest.mockito.MockitoSugar
import org.scalatestplus.play.
import org.scalatestplus.play.PlaySpec
import play.api.inject.bind
import play.api.inject.guice.GuiceApplicationBuilder
import play.api.inject.guice.GuiceableModule
import play.api.libs.json.
import play.api.libs.json.Json
import product.model.OfferDetail
import product.model.OfferList
import product.services.market.walmart.WalmartRepository
import org.mockito.Mockito.
import org.mockito.Matchers.
import play.api.test.Helpers.
import play.api.test.CSRFTokenHelper._
import play.api.test.WithApplication
import play.api.test.FakeRequest
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import org.scalatest.junit.JUnitRunner

@RunWith(classOf[JUnitRunner]) class ProductControllerSpec extends PlaySpec with MockitoSugar {

/ MOCK data / val productList = Json.parse(Source.fromFile("conf/app/sample_offer.json").getLines.mkString).as[OfferList]

val myMock = mock[DataRepository]
when(myMock.search(any[Map[String,String]])) thenReturn Future.successful(Some(productList))

val appMock = new GuiceApplicationBuilder() .overrides(bind[DataRepository].toInstance(myMock)) .build "index" in new WithApplication(appMock) {
val request = FakeRequest(GET, "/products").withHeaders(HOST -> "localhost:9000") val response = route(app, request).get val json = contentAsJson(response) val elem0 = (json \ "list")(0) status(response) mustBe OK (elem0 \ "id").as[String] mustBe "1" (elem0 \ "name").as[String] mustBe "prod 1"
} }

comments powered by Disqus