Many times people have asked me how do I do mocking when writing tests for Scala applications. Since testing is a great deal for us (see Simplified Testing with ScalaTest and Custom Matchers) seems that mocking has to be an integral part of our testing technique, so let’s explore some thoughts on this area.

Let’s start by showing a common problem that occurs to us every single day. Please, notice that the example could be very simplistic, but given a context, it can be extrapolated to everyday realistic problems.

Our problem domain is the one related to Application User Manipulation.

Let’s define some high-level abstractions from the very beginning.

First, we have an interface that store and retrieve objects from some kind of storage. As you may see, this definition is very abstract, and we need, at some point, specializations of it.

Now, we can define another abstraction closer to our domain.

UserRepository is the abstraction that represents how we are going to manage the users in our application.

At this point, we need to implement UserRepository and it needs a concrete representation of DB to work with.

Let’s start by writing some tests.

There is nothing unusual about this test. The only thing it does is make sure a user is recoverable once it has been added it. The problem with it is that it needs some instance of DB.

At this point, we can add a mocking lib to our dependencies and start mocking DB; but the question is if that is really necessary.

What about if just implement a version of it we can use in our tests?

Now, in our tests, we need to initialize InMemDB before running them.

In some way, we are creating a real implementation of DB which is fine for many cases, but sometimes we want to have more flexibility and in here is where mocking libs shine.

In this case, we don’t have to implement DB to use it. We can mock/simulate the behavior of it in the way we want. However, in order to setup the mocking, extra steps are required.

Let’s write another test using this technique.

In here we are testing that the predicate (user.name.length ≤ 3) is being executed.

As you can see, it is not hard to set up these mocks, but it could also be another way to do the same without introducing extra dependencies to our tests.

What about if we could write the same test in the following way.

We can actually create an instance of DB and implement it inline. The drawback is that we need to have the other functions there as well, even when we are not using them.

We can cheat around of this by creating another trait with default implementation and then using the new one within the tests.

And now we can rewrite our test as follow.

It is important to remember that in here we are not testing DB at all. All that matters here is to be able to successfully test UserRepository.

There is at least one more way to replace DB for something we could use in UserRepository. We could mix in DB with our test class.

In this particular way, we need to implement the DB functions inside our test class which makes it an instance of DB. That is kind of the same we did with UserDBForTesting, but in this case, we don’t need an extra class, and the implementation is exactly what our test needs and nothing else.