UIViewController + Decorator = Unit Test

Rafał Prążyński
Nerd For Tech
2 min readDec 26, 2021

--

Hello There!

Today I want to show you how at first glance some UI objects configuration in UIViewController from untestable will become testable!

What is the advantage of using Decorator pattern?

Decorator is structural software design pattern and with its help we can separate static setup of UI properties like:

  • texts,
  • text color,
  • font,
  • border color,
  • border width,
  • etc.

Of course we can create specific class with encapsulated setup. Let’s take simple example for purpose of this article:

Define some classes for UIButton:
BorderButton - class with setup properties for layer.border
BoldFontButton - class with setup font for .boldSystemFont(ofSize:)

And now let’s assume the BoldFontButton inherits from BorderButton, because we want BoldFontButton have borders. For this time it is all good. But, now there is a situation where we want BoldFontButton not to have borders. In that case we need:

  • Remove inheritance from BoldFontButton and add configuration borders in all places,
  • Remove borders in view where don’t want borders,

Both cases cause difficulties especially the second one because it obscures the intention BoldFontButton class and we can’t write test for checking properly values.

To untie this problem we can use Decorator pattern which give us posibility to move some UI configuration to external class and thanks to that UI class like UIButton from above example will not pay a cost for inheritance unwanted behaviors.

There are two ways:

  1. Create dedicated Decorator for border and for bold font,
  2. Create one dedicated Decorator for view where we will use it.

I’ll present here thesecond solution.

SOLUTION

First, let’s declare UIViewController with private UIButton setup:

Now, let’s declare Decorator for our ViewController and move all setup there:

And inject our Decorator in to ViewController:

From this point we have possibility to test our configuration for UIButton:

That’s all. Done!

Conclusion:

With this approach we receive the following benefits:

  • UIViewController will not swell because of configuration for UI objects,
  • Possibility to test UI configuration,
  • Readable UI configuration,
  • UI configuration is separate from UIViewController.

Thank you for taking the time to read up to this point.

Good luck!

Full code: https://github.com/Rafal-Prazynski/Decorator.Medium

--

--