12.6. Pretending that a String Is a File

Problem

Typically for the purposes of testing, you want to pretend that a String is a file.

Solution

Because Scala.fromFile and Scala.fromString both extend scala.io.Source, they are easily interchangeable. As long as your method takes a Source reference, you can pass it the BufferedSource you get from calling Source.fromFile, or the Source you get from calling Source.fromString.

For example, the following method takes a Source object and prints the lines it contains:

import io.Source

def printLines(source: Source) {
  for (line <- source.getLines) {
    println(line)
  }
}

It can be called when the source is constructed from a String:

val s = Source.fromString("foo\nbar\n")
printLines(s)

It can also be called when the source is a file:

val f = Source.fromFile("/Users/Al/.bash_profile")
printLines(f)

Discussion

When writing unit tests, you might have a method like this that you’d like to test:

package foo

object FileUtils {

  def getLinesUppercased(source: io.Source): List[String] = {
    (for (line <- source.getLines) yield line.toUpperCase).toList
  }

}

As shown in the following ScalaTest tests, you can test the getLinesUppercased method by passing it either a Source from a file or a String:

package foo

import org.scalatest.{FunSuite, BeforeAndAfter}
import scala.io.Source

class FileUtilTests extends FunSuite with BeforeAndAfter {

  var source: Source = _
  after { source.close }

  // assumes the file has the string "foo" as its first line
  test("1 - foo file") {
    source 

Get Scala Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.