Tests Everywhere - Scala
Tags: test, scala, scalatest, tutorial
Published: 2023-11-23 00:25:51

{% github rogervinas/tests-everywhere no-readme %}

[Scala](https://www.scala-lang.org/) testing [this simple Hello World](https://dev.to/rogervinas/tests-tests-everywhere-1b6h) with [ScalaTest](https://www.scalatest.org/) and [Mockito](https://www.scalatest.org/plus/mockito)

- [Show me the code](#show-me-the-code)
  - [Implementation](#implementation)
  - [Test](#test)
- [Run this project using 🐳 docker](https://github.com/rogervinas/tests-everywhere/tree/main/scala#run-this-project-using--docker)
- [Run this project locally](https://github.com/rogervinas/tests-everywhere/tree/main/scala#run-this-project-locally)

## Show me the code

### Implementation

1. Create `HelloMessage` class in [HelloMessage.scala](https://github.com/rogervinas/tests-everywhere/blob/main/scala/src/main/scala/org/hello/HelloMessage.scala):

```scala
class HelloMessage:
  def text: String = "Hello World!"
```

We can create it as a class as [Mockito](https://www.scalatest.org/plus/mockito) is able to mock final classes.

2. Same way create `HelloConsole` class in [HelloConsole.scala](https://github.com/rogervinas/tests-everywhere/blob/main/scala/src/main/scala/org/hello/HelloConsole.scala):

```scala
class HelloConsole:
  def print(text: String): Unit =
    println(text)
```

3. Create `HelloApp` class in [HelloApp.scala](https://github.com/rogervinas/tests-everywhere/blob/main/scala/src/main/scala/org/hello/HelloApp.scala):

```scala
class HelloApp(message: HelloMessage, console: HelloConsole):
  def printHello(): Unit =
    console.print(message.text)
```

4. Create main class in [Main.scala](https://github.com/rogervinas/tests-everywhere/blob/main/scala/src/main/scala/org/hello/Main.scala) that wraps it all together:

```scala
@main def main(): Unit =
  val message = HelloMessage()
  val console = HelloConsole()
  val app = HelloApp(message, console)
  app.printHello()
```

### Test

Following [ScalaTest > Writing your first test](https://www.scalatest.org/user_guide/writing_your_first_test) and [ScalaTest + Mockito](https://www.scalatest.org/plus/mockito) guides ...

1. Test `HelloMessage` in [HelloMessageSpec.scala](https://github.com/rogervinas/tests-everywhere/blob/main/scala/src/test/scala/org/hello/HelloMessageSpec.scala):

```scala
class HelloMessageSpec extends AnyFlatSpec {

  "A HelloMessage" should "return hello world" in {
    val message = HelloMessage()
    assertResult(message.text) {
      "Hello World!"
    }
  }
}
```

2. Test `HelloApp` in [HelloAppSpec.scala](https://github.com/rogervinas/tests-everywhere/blob/main/scala/src/test/scala/org/hello/HelloAppSpec.scala):

```scala
class HelloAppSpec extends AnyFlatSpec {

  "A HelloApp" should "print hello message" in {
    val messageText = "Hello Test!"

    // 2.1 Create a mock of HelloMessage
    val message = mock[HelloMessage]
    // 2.2 Return "Hello Test!" whenever text is called
    when(message.text).thenReturn(messageText)

    // 2.3 Create a mock of HelloConsole
    val console = mock[HelloConsole]

    // 2.4 Create a HelloApp, the one we want to test, passing the mocks
    val app = HelloApp(message, console)
    // 2.5 Execute the method we want to test
    app.printHello()

    // 2.6 Verify HelloConsole mock print() method
    // has been called once with "Hello Test!"
    verify(console).print(messageText)
  }
}
```

3. Test output should look like:

```
[info] HelloMessageSpec:
[info] A HelloMessage
[info] - should return hello world
[info] HelloAppSpec:
[info] A HelloApp
[info] - should print hello message
[info] Run completed in 515 milliseconds.
[info] Total number of tests run: 2
[info] Suites: completed 2, aborted 0
[info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
[success] Total time: 6 s
```

Happy Testing! 💙