Testing Bank Kata in PureScript

Posted on March 18, 2019 by Riccardo

Intro

Last week we’ve had some fun solving the Bank Kata in PureScript. Now it’s time to add some unit tests.

In particular, we are going to test the three main functions of the kata:

The Tests

Let’s start with deposit:

Unfortunately, it uses Effect. That means, it does something impure we cannot check in a unit test.

We can fix that easily by changing the type signature into

In other words, we don’t specify the specific monad (Effect) anymore. We just say that deposit uses a monad m as a base monad for StateT.

Sadly, that does not compile. In fact, the type signature is telling a lie. In the body of the function we do ts <- lift nowDateTime. As explained in the previous post, that obliges the function to use Effect.

Luckily, this is an easy fix. Instead of using nowDateTime in deposit, we will just inject it:

The downside of this refactoring is that we need to change the production code from deposit 500 to deposit nowDateTime 500. The upside is that we can use a unit testable monad now. Not that bad!

Here’s the test

We wrap timestamp :: DateTime in the Identity monad so that deposit (Identity timestamp) amount has type StateT (Array Transaction) Identity Unit. That means, execStateT returns Identity (Array Transaction).

Testing withdraw follows the exact same pattern so we are not going to cover that.

Let’s move to printStatement:

Here the story is really similar to what we did to deposit:

And the corresponding unit test:

Notice that as a base monad we use Writer. This monad gives us access to tell which allows us to append to an accumulator. That way printStatement “writes” the statement in the accumulator instead of the console.

Show me the Code

Code:

Tests:

Outro

If you liked the post and want to help spread the word, please make some noise 🤘 But only if you really liked it. Otherwise, please feel free to comment or tweet me with any suggestions or feedback. And please do cause I need help with my FP!