Jason Marsh
Jason Marsh

Reputation: 380

Mock function's behvaiour in Mocktio Scala

I'm working on a Scala and Play application, and trying to write a mock for one of my unit test.

def getActionAsBase64(
    appName: String = null,
    taskType: String = null,
    taskName: String = null
  ): String = {
    val pwd = System.getProperty("user.dir")
    val filePath = Paths.get(pwd, "..", "tasks", appName, taskType, taskName, taskName + ".zip").toString
    val simplified = Files.simplifyPath(filePath)

    // Reading the file as a FileInputStream
    val file = new File(simplified)
    val in = new FileInputStream(file)
    val bytes = new Array[Byte](file.length.toInt)
    in.read(bytes) // stream inserts bytes into the array
    in.close()

    // Encoding the file using Base64encoder
    val encoded =
      new BASE64Encoder()
        .encode(bytes)
        .replace("\n", "")
        .replace("\r", "")
    return encoded.toString
  }

Above is my original code and I am trying to mock the behaviour of in.read, and make it inject an arbitrary data to the bytes array.

So far I was only able to find how to do simple mock using thenReturn approach, which mocks the returning value.

In my situation, again, I want to mock the behaviour of the function, and ideally, it should do something like

def mockRead(bytes) {
   // mutate the bytes parameter
}

Upvotes: 0

Views: 113

Answers (1)

prayagupadhyay
prayagupadhyay

Reputation: 31232

you need a way to either inject a mock file or a function that reads file,

Example of API that accepts a function,

  import java.util.Base64

  object Api {

    def getActionAsBase64(fileBytesFn: (String, String, String) => Array[Byte],
                          appName: String,
                          taskType: String,
                          taskName: String): String = {

      val encoded = new String(Base64.getEncoder
        .encode(fileBytesFn(appName, taskName, taskName)))
        .replace("\n", "")
        .replace("\r", "")

      encoded
    }
  }

That way you can pass a test func that reads a file,

  test("test a function") {

    val mock = (_: String, _: String, _: String) => "prayagupd".getBytes()

    val d = Api.getActionAsBase64(mock, "any app name", "taskName", "taskName")

    assert(d == "cHJheWFndXBk")
  }

Alternative way can be to pass in stubbed func,

  test("test a function II") {

    val stbbedFn = stubFunction[String, String, String, Array[Byte]]
    stbbedFn.when("any appName", "any taskType", "any taskName").returns("prayagupd".getBytes())

    val d = Api.getActionAsBase64(stbbedFn, "any appName", "any taskType", "any taskName")

    assert(d == "cHJheWFndXBk")
  }

Upvotes: 2

Related Questions