Functional Programming, Simpler Unit Testing Part 2

Leandro Bolívar
Pragmatic Scala
Published in
3 min readApr 6, 2016

In Functional Programming, Simpler Unit Testing Part 1 I illustrated how we can use higher order functions and function composition in order to deal with methods that produce side effects and how we can test our code more efficiently by isolating these side effects in small functions. I also chose not to test the methods that access the repository and web services because it is better handled by mocking objects, which we will learn in this part of the tutorial.

There is always an open debate on which is the smallest unit to test in our code, if it is truly isolated or if it should consider other components of code to test the expected behaviour (read Martin Fowler’s blog post about Unit Testing). In our example, our units are functions that have specific responsibilities and can describe behaviours or tasks by composing them through higher order functions. We treat with special care those functions that produce side effects so that they remain completely isolated so when the time come to test them, we can deal with the objects that interact with databases or web services through mocks. For such tasks, I use Specs2 which is a library that uses Mockito to create the mock objects needed. This testing library is FP oriented and the infix notation helps in making yours tests more expressive and self explanatory.

Lets go right to the tests. In the Account Services class we wrote several functions which we test one by one, including the ones that we skipped in part 1. We define a spec class called AccountServicesSpec, set it up with out mock objects, define a test class that extends AccountsServices so we can overwrite the external dependencies with our mocks, we include the before method which is called previous to each spec execution and then we lay down the tests corresponding to each function:

We can point out the following:

  • The infix notation is a great help when expressing what we are expecting: result must have size 1 in case of asserting the size of a list, result must beEqualto(0.2) in case we are expecting a specific value. This makes our tests more explicit and it is easier to maintain or change in case the code gets modified.
  • The method before is used to do the setup needed before each test so that you don’t have to repeat it in every spec, keeping yourself DRY. It is useful when we need to reset the mock call counter (yes, the mock preserves a counter that it is increased every time it is called and it does not reset itself after each spec is done) and when you need to stub some of the mocked object’s methods or properties.
  • Mocking the objects that produce side effects provides us with the isolation needed to test the functions that contain those objects and assert for expected values and method calls. This way we keep our premise: every function is a unit and we can compose complex behaviours by composing the functions that we need. The higher order functions help us contain those functionalities and, in a way, make dependency injection directly to them.

Specs2 has a lot of more features than those shown in this example, if you want to have a closer look there are specs2 examples available. We still can make more out of this library by using something called spies. Spies are partially mocked objects that you can instantiate and use them as we used our AccountServicesTest class but with the ability to stub its functions and assert calls made to them. I am going to leave that to the third part of this tutorial. For more insight you can check out the links I included to the Specs2 homepage, the documentation is quite good.

--

--

Leandro Bolívar
Pragmatic Scala

The question isn't who is going to let me; it's who is going to stop me. Ayn Rand.