Advertisement
mitrakov

Simple Unit Test

Aug 7th, 2018
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Scala 5.79 KB | None | 0 0
  1. // Let's create a simple Unit Test for Play Framework project!
  2.  
  3. // BuildingDao.scala (taken from https://pastebin.com/yNiBWTpf)
  4. package dao
  5.  
  6. import javax.inject.Inject
  7. import scala.concurrent.Future
  8. import play.api.db.slick.{DatabaseConfigProvider, HasDatabaseConfigProvider}
  9. import play.db.NamedDatabase
  10. import slick.jdbc.JdbcProfile
  11. import slick.lifted.ProvenShape
  12.  
  13. case class Building(buildingId: Option[Long], number: Option[Int], name: String)
  14.  
  15. class BuildingDao @Inject()(
  16.     @NamedDatabase("students") val dbConfigProvider: DatabaseConfigProvider
  17.   ) extends HasDatabaseConfigProvider[JdbcProfile] {
  18.  
  19.   import profile.api._
  20.  
  21.   private class BuildingTable(tag: Tag) extends Table[Building](tag, "building") {
  22.     def buildingId: Rep[Long] = column[Long]("building_id", O.PrimaryKey, O.AutoInc)
  23.     def number: Rep[Option[Int]] = column[Option[Int]]("number")
  24.     def name: Rep[String] = column[String]("name")
  25.  
  26.     override def * : ProvenShape[Building] = (buildingId.?, number, name) <> (Building.tupled, Building.unapply)
  27.   }
  28.  
  29.   private lazy val table = TableQuery[BuildingTable]
  30.  
  31.   def findByNumber(number: Int): Future[Option[Building]] = {
  32.     val query = table.filter(_.number === number).result
  33.     println(query.statements.mkString)
  34.     db.run(query.headOption)
  35.   }
  36. }
  37.  
  38.  
  39.  
  40. // CampusController.scala
  41. package controllers
  42.  
  43. import javax.inject.Inject
  44. import scala.concurrent.ExecutionContext
  45. import play.api.libs.json.Json
  46. import play.api.mvc._
  47. import dao.BuildingDao
  48.  
  49. /**
  50.  * CampusController
  51.  * @param cc Controller Components
  52.  */
  53. class CampusController @Inject()(
  54.     buildingDao: BuildingDao,
  55.     cc: ControllerComponents
  56.   )(implicit val ec: ExecutionContext) extends AbstractController(cc) {
  57.  
  58.   def health: Action[AnyContent] = Action {
  59.     Ok("Service is OK")
  60.   }
  61.  
  62.   def getBuildingByNumber(num: Int): Action[AnyContent] = Action.async {
  63.     buildingDao.findByNumber(num) map {
  64.       case Some(bld) => Ok(Json.toJson("id" -> bld.buildingId, "name" -> bld.name, "number" -> bld.number))
  65.       case None => NotFound(s"Building with num = $num not found")
  66.     }
  67.   }
  68. }
  69.  
  70.  
  71.  
  72. // and finally the Unit Test itself
  73. // CampusControllerSpec.scala
  74. import controllers.CampusController
  75.  
  76. import scala.concurrent.Future
  77. import org.mockito.Mockito._
  78. import org.scalatest.BeforeAndAfterEach
  79. import org.scalatest.mockito.MockitoSugar
  80. import org.scalatestplus.play.PlaySpec
  81. import play.api.libs.json.Json
  82. import play.api.test.FakeRequest
  83. import play.api.test.Helpers._
  84. import play.mvc.Http.MimeTypes
  85. import dao.{Building, BuildingDao}
  86.  
  87. /**
  88.  * Unit test for CampusController. Just extend "PlaySpec" class
  89.  */
  90. class CampusControllerSpec extends PlaySpec with MockitoSugar with BeforeAndAfterEach {
  91.   // some common constants
  92.   val buildingId = 127
  93.   val buildingName = "Mathematics"
  94.  
  95.   // since resetting stubs is considered to be bad practice, we will re-create the stubs before each test
  96.   var buildingDao: BuildingDao = _
  97.   var controller: CampusController = _
  98.  
  99.   // "beforeEach()" will be executed before each test; just mix-in "BeforeAndAfterEach" trait to override it
  100.   override protected def beforeEach(): Unit = {
  101.     // let's mock BuildingDao's behaviour: we suppose that Building #5 exists, and Building #6 doesn't
  102.     buildingDao = mock[BuildingDao]    // mix-in "MockitoSugar" trait for this
  103.     when (buildingDao.findByNumber(5)) thenReturn Future.successful(Some(Building(Some(buildingId), Some(5), buildingName)))
  104.     when (buildingDao.findByNumber(6)) thenReturn Future.successful(None)
  105.  
  106.     // also we will use predefined ControllerComponents for our controller
  107.     val cc = stubControllerComponents()
  108.     implicit val ec = cc.executionContext
  109.  
  110.     // create our Controller for testing
  111.     controller = new CampusController(buildingDao, cc)
  112.   }
  113.  
  114.   "CampusController" when {
  115.     "empty request received" should {
  116.       "return OK 200" in {
  117.         val result = controller.health.apply(FakeRequest())            // basic test
  118.         status(result) mustBe OK
  119.         contentAsString(result) mustBe "Service is OK"
  120.         contentAsString(result) must include("is")
  121.         contentAsString(result) must startWith("Service")
  122.         contentAsString(result) must endWith("OK")
  123.       }
  124.     }
  125.  
  126.     "request for an existing building received" should {
  127.       "return OK 200" in {
  128.         val number = 5
  129.         val expectedJson = Json.toJson("id" -> buildingId, "name" -> buildingName, "number" -> number)
  130.  
  131.         val result = controller.getBuildingByNumber(number).apply(FakeRequest()) // will return info about Building #5
  132.         status(result) mustBe OK
  133.         contentType(result) mustBe Some(MimeTypes.JSON)
  134.         contentAsJson(result) mustBe expectedJson
  135.       }
  136.     }
  137.  
  138.     "request for a non-existing building received" should {
  139.       "return NOT_FOUND 404" in {
  140.         val number = 6
  141.  
  142.         val result = controller.getBuildingByNumber(number).apply(FakeRequest()) // will return "Building #6 not found"
  143.         status(result) mustBe NOT_FOUND
  144.         contentAsString(result) mustBe s"Building with num = $number not found"
  145.       }
  146.     }
  147.   }
  148. }
  149.  
  150.  
  151.  
  152.     // sbt testOnly *CampusControllerSpec
  153.     // output:
  154.  
  155.     // [info] CampusControllerSpec:
  156.     // [info] CampusController
  157.     // [info]   when empty request received
  158.     // [info]   - should return OK 200
  159.     // [info]   when request for an existing building received
  160.     // [info]   - should return OK 200
  161.     // [info]   when request for a non-existing building received
  162.     // [info]   - should return NOT_FOUND 404
  163.     // [info] ScalaTest
  164.     // [info] Run completed in 2 seconds, 820 milliseconds.
  165.     // [info] Total number of tests run: 3
  166.     // [info] Suites: completed 1, aborted 0
  167.     // [info] Tests: succeeded 3, failed 0, canceled 0, ignored 0, pending 0
  168.     // [info] All tests passed.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement