FuncCheck — Test your methods

Cristian Lupu
Crunchyroll
Published in
2 min readDec 2, 2021

Introduction

Photo by Max Duzij on Unsplash

When we are writing unit tests in a BDD style, we may want to check with what value parameter was called a dependency method or how many times that dependency method was called after some action in your testing instance.

And we often end up writing code like this:

Looks like A LOT of boilerplate.

Develop FuncCheck class

The iOS team uses an internal framework with test helpers and the FuncCheck class is one of them.

What if we encapsulate all of this logic in one class? Let’s begin. The final interface should look more elegant:

And how are we gonna use it in a test? We will surely need call count, a computed property to determine if this method was called, and the stack of invocations along with its parameters.

This class should not be tied to a concrete type of parameter, and for that, we will use generics. Let’s add the call count:

Easy enough. Using callCount facilitates the creation of a computed property named wasCalled.

Next, we need to implement the stack of invocations.

Most of the time, we will not need the whole stack but only the last:

Now, we can implement a handy method wasCalled(with:):

Another method that may be useful in testing is getting a callback when the invocation started.

Another wish in testing is checking whether a method was called after or before another method. The implementation is simple: we create a private date variable and reset it on every call, then we can compare dates with other ones.

What if your methods don’t accept any parameters?

You can still use FuncCheck<Void> or a sugar extension over FuncCheck class:

What if your methods accept more than one argument? How can I use FuncCheck if there is only one generic parameter?

In this case, the best solution is to use Swift tuples.

Are you using Nimble in your testing?

We’ve prepared some extensions to facilitate the FuncCheck usage.

Let’s see how it looks in the battle:

Stub the return values of the method

What if your method has a return value and you also want to stub that value?
We propose this solution:

Conclusion

The FuncCheck was developed to facilitate writing the tests and their readability. Another solution to this is using code generation. An example is the Sourcery with the AutoMockable template. Thus every class needed to be mocked will have these properties and methods from code generation.

--

--