Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock scala readLine

I want to write a unit test for my main function where there is a readLine() loop.

I have tried the following which is java based. I think readLine() might need System.in as inputStream. But it doesn't work. ScalaTest is blocked on the readLine() waiting for inputs.

"readLine" should "work" in {
  val in = new ByteArrayInputStream("abc".getBytes)
  System.setIn(in)
  readLine() === "tester"
}

Any ideas? Thank you.

like image 668
Hao Ren Avatar asked Apr 06 '15 15:04

Hao Ren


People also ask

How to use Scala read file?

To use the Scala Read File we need to have the Scala.io.Source imported that has the method to read the File. Console.readline //used to read the File from the console only. We can read various files from Scala from the location in our local system and do operation over the File I/O. Let us see some methods how to read files over Scala: 1.

How do I read command-line input in scalac?

There are several ways to read command-line input, but the easiest way is to use the readLine method in the scala.io.StdIn package. To use it, you need to first import it, like this: To demonstrate how this works, let’s create a little example. Put this source code in a file named HelloInteractive.scala: Then compile it with scalac:

How do I mock a formatter in Scala?

With ScalaMock, we can test the interactions between this method and a given Formatter. To be able to mock things, you need to mix-in the org.scalamock.scalatest.MockFactory into your test class. For example, we can check that the name is actually used in the call to our formatter, and that it is called once (and only once):

What mocking frameworks can I use with Scalatest?

Here are links to the mocking frameworks that can be used with ScalaTest: ScalaMock is a native, open-source Scala mocking framework written by Paul Butcher that allows you to mock objects and functions. ScalaMock supports three different mocking styles:


2 Answers

The correct way to Unit Test it is to follow the "ports and adapters" pattern.

So you should have an interface that is the 'port' to the console reader so you could mock it in your unit test.

In addition you should have a Integration Test that verifies that your 'adapter' actually works against the real console.

According to the title of your question I guess you want to do an Integration test. You were almost there. You called a deprecated method that is deprecated since Scala 2.11.0. This code should work -

"readLine" should "work" in {
  val in = new ByteArrayInputStream("abc".getBytes)
  System.setIn(in)
  StdIn.readLine() === "abc"
}
like image 104
Maxim Avatar answered Oct 12 '22 00:10

Maxim


Maxim's solution actually didn't work for me (anymore?). So to help others who face the same issue:

val in = new ByteArrayInputStream(("abc").getBytes)

Console.withIn(in)  {
    assert(StdIn.readLine() === "abc")
}
like image 41
Tom Lous Avatar answered Oct 11 '22 22:10

Tom Lous