Mock Unit Testing using Mockito in Play Scala project


During Unit Testing in a Play Scala project, there arises a need to Mock certain Objects or Traits which are used in the unit, so that the unit being tested has a consistent interaction with its outside dependencies. But due to tight coupling or external dependencies, objects cannot be tested as a unit. So, we need to mock those external dependencies by adding fake external dependencies to it.

This can be done with the help of various mocking frameworks like Mockito, EasyMock or jMock. Selecting an appropriate mocking framework depends on the application that is being built.

This blog will tell you how to use Mockito for mocking objects or traits in a Play Scala project along with ScalaTest.

Mockito is an open source testing framework for Java/Scala released under the MIT License. The framework allows the creation of test double objects (mock objects) in automated unit tests for the purpose of Test-driven Development (TDD).

To use Mockito in a Play Scala project follow these easy steps & you are done.

1. Add following dependencies to build.sbt ( or build.scala for version Play 2.1.x or earlier).

"org.scalatest" % "scalatest_2.10" % "2.0" % "test"
"org.mockito" % "mockito-core" % "1.9.5" % "test"

First one is for Scalatest and second one is for Mockito.

2. Import following libraries in your unit testing code.

import org.specs2.mock.Mockito
import org.specs2.mutable.Specification
import org.mockito.Mockito._
import org.mockito.Matchers._

Also, import the necessary Scalatest libraries required for Unit Testing of your application

3. Now here is an example code of a test case using Mockito.

class UserControllerTest extends Specification with Mockito {

 val user = User("knoldus_software_llp@gmail.com", encryptPassword("password"), "Knoldus Software LLP")

 val mockUserDALObject = mock[UserDALComponent]

 val userController = new UserController(mockUserDALObject)

 "UserControllerTesting: addUser is successful" in {
  running(FakeApplication()) {
   when(mockUserDALObject.insertUser(any[User])).thenReturn(1)
   when(mockUserDALObject.searchUserByEmail("knoldus_software_llp@gmail.com")).thenReturn(None)
   val result = userController.addUser(FakeRequest().withFormUrlEncodedBody("name" -> "Knoldus Software LLP", "email" ->
   "knoldus_software_llp@gmail.com", "password" -> "password", "confirm_password" -> "password").withHeaders(CONTENT_TYPE -> "application/x-www-form-urlencoded"))
   status(result) must equalTo(200)
  }
 }
}

In this example we want to test addUser function(unit) of userController.scala.

addUser’s definition is as follows :-

class UserController(userDAL: UserDALComponent) extends Controller{
 def addUser: Action[play.api.mvc.AnyContent] = Action { implicit request =>
  userForm.bindFromRequest.fold(
   formWithErrors => {
    Redirect("/")
   },
   userData => {
    searchUserByEmail(userData.email) match {
     case None =>
      val encryptedPassword = encryptPassword(userData.password)
      val response = insertUser(User(userData.email, encryptedPassword, userData.name))
      Redirect("/user/login")
     case Some(user) => Ok(views.html.user.signup(userForm, "Email Id Already Exist !"))

     }
   })
  }
}

object UserController extends UserController(UserDAL)

As we can see that addUser function of userController.scala is dependent on insertUser & searchUserByEmail functions to add & search new user to/from database. But, while Unit Testing we want to test only addUser function of userController.scala & not insertUser function. So, to mock insertUser function, we made a mock object mockUserDALObject which mocked UserDALComponent.

UserDALComponent & insertUser are defined as follows :-

trait UserDALComponent {
  def insertUser(user: User): Int
  def searchUserByEmail(email: String): Option[String]
}

object UserDAL extends domains with UserDALComponent {

 /**
 * Inserting new user to DB
 */
 def insertUser(user: User): Int = {
  Connection.databaseObject withSession { implicit session =>
   users.insert(user)
  }
 }

 def searchUserByEmail(email: String): Option[String] = {
  Connection.databaseObject withSession { implicit session: Session =>
   (for { user <- users if (user.email === email) } yield user.email).firstOption
   }
  }
}

Then we made an object userController of UserController class, with mocked object as follows :-

val userController = new UserController(mockUserDALObject)

Using this object we can test all units/functions of UserController without using any external dependency.

Note :- For mocking any object a Trait of that object has to be created first & a Class & Object of the unit being tested. (As we have shown in above example)

This entry was posted in Play Framework, Scala and tagged , , . Bookmark the permalink.

One Response to Mock Unit Testing using Mockito in Play Scala project

  1. Himanshu Gupta says:

    You want to use ScalaTest and import org.spec2 – this is not valid as of today.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s