Functional Programming, Simpler Unit Testing Part 1

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

From my experience in Scala, one of the most annoying things to do is to test methods that have inner calls to other private or public methods since there is no way to stub them or mock the objects that those methods use or produce. The issue gets more complicated if an inner method call produces side effects (database inserts, web service calls, etc) and you don’t have a way to control how those actions are executed, this compromises the necessary isolation of your unit test. To avoid these testing pains I resorted to functional programming in Scala, implementing anonymous and higher order functions.

A higher order function, as explained in the Scala Documentation, is a function that take other functions as parameters. Lets say we have a bank client that just earned a 10% interest value on all his accounts and you want to apply those changes to it. You will want to query all his accounts, add the 10% interest value to them and store the corresponding results.

The account domain:

Account Services class:

We assume that AccountRepository has all the insert, update, get and delete methods for handling database persistance of our account objects. The IntegrationServices class defines an API for web services, in this case we define one that is responsible for querying the current interest rate. As you can see, the method execute only takes the client id as a parameter, then we just call the inner methods and thanks to the function composition and currying you can see clearly the flow of the process: pass the client id, get the current interest rate, add it to the account’s amount and then update the accounts.

Now we want to test our AccountServices class with a simple suit made just by asserts. For that we are going to define anonymous functions so we can pass expected results to the higher order ones. In these tests we will omit testing the functions that produce side effects, we’ll to learn how to do it using mocking and stubbing in the second part of this tutorial.

Testing our service:

We can point out the following:

  • There are no private methods: every method defined could be tested because they are not defined as private.
  • There is no need to test explicitly the method execute: this method is defined so that the client class or object can pass the client id and obtain the expected result. We are only testing the higher order function that gets done the required task.
  • No problem with side effects: every function got replaced by an anonymous function with desired results, this way we avoid dealing with unwanted side effects from inner methods which calls cannot be controlled in regular testing.

There is a much efficient way of testing our example by using mocks and stubs which allow us to assert passed function calls, mock objects that have side effects (like the AccountRepository and IntegrationServices) and test for how our class handles errors (which is not well defined in our example). We will show how to do that in part 2 of Functional Programming, Simpler Unit Testing

--

--

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.