Mocks are evil

When I’m presenting my TestTools for PHPUnit to developers, I often get the feedback that the resulting tests are just component tests and not true unit tests. This post will explain the rationale behind this decision and how less mocking can improve everyone’s testing experience and productivity.

The difference between unit and component tests

Simply put, component tests are like unit tests except that you don’t mock dependencies by default but use real objects (ideally via dependency injection). Mocking is creating objects that simulate the behaviour of real objects.

My way of testing PHP code

The tools contain two parts: An integrated DI container for easy dependency injection using YAML config files (instead of mocking every single class dependency or doing the dependency injection manually) and self-initializing fixtures to replace storage backends such as SQL databases or REST services with record and playback fixtures. I’ve been using them for many years with great success in projects large and small.

Here’s an example of a test case built with TestTools – note the setUp() method, which get’s the ready-to-use object from the dependency injection container:

use TestTools\TestCase\UnitTestCase;

class FooTest extends UnitTestCase
    protected $foo;

    public function setUp()
        $this->foo = $this->get('foo');

    public function testBar()
        $result = $this->foo->bar('Pi', 2);
        $this->assertEquals(3.14, $result);

You’ll get fresh instances in every test, so there is no global state that could harm our tests. From that point of view, they run in isolation. The compiled service definitions in the container are reused however for performance reasons.

This approach let’s you create tests much faster, you’ll get a higher code coverage and need to invest less effort in maintenance. It simply saves a lot of time and money. There might be similar testing tools and libraries for other programming languages. My tools are actually inspired by something I’ve seen in JavaScript before.

Excessive mocking is an anti-pattern and hurts your productivity

Finding true unit tests out there with 100% mocked dependencies is extremely difficult. And there’s a reason for that.

Here’s a great explanation how mocking interferes with our testing goals:

Mocks interact with the internal logic of your classes and therefore will change every time that logic changes. Also, we often find ourselves in situations when we mock a lot and therefore we mostly test how we initialize our mocks rather than how our business logic works. So mocks are evil, but sometimes are necessary. Component Tests will free us from unnecessary mocking.Stanislav Bashkyrtsev

Mocks are required to be able to test sometimes, but since mocking can be a costly endeavour, you should try to avoid their widespread usage and prefer component tests instead. They do no harm – quite the contrary: You can instantly see, how the real objects interact with each other instead of waiting for functional tests.

Mocking libraries do have their place though. As with most tools, they are a valuable tool in your tool box for specific purposes. If you inherit a large, badly written legacy system, otherwise known as a Big Ball of Mud, the first thing you want to do before changing the code is get some tests around what is there already. These tests are called characteristics tests. This is where you need to test what the current functionality does. This functionality may be wrong or buggy, but you want to get a test suite in place so that you know whether you have broken/changed anything as part of your refactoring. Normally because of excessive class coupling you will need to use a mocking library to write these tests. In this scenario I think mocking libraries are perfect and this is when I would use them, but as you start refactoring your code and trying to introduce some of the solid principles you need to plan for how you are going to remove these mocks and write simpler tests.Stephen Haunts: All Your Mocks are Evil!!

In theory, true unit tests can be a bit more precise when it comes to finding a broken line of code, because all classes are tested in complete isolation. In practice, component tests will also provide you with a stack trace that points you to the right line of code. In the worst case, more than one test case fails, if just one class or function is broken – that will give you even more information about the issue.

The need for excessive mocking – especially when working with older software libraries – was the number one reason, why I refused to write unit tests a long time ago. After discovering the usefulness of component tests in conjunction with dependency injection, I started to love testing and I can not work without tests anymore.

Even code that depends on databases or Web services, can be easily tested using self-initializing fixtures instead of hand-written mocks. The only thing they can not properly simulate is state, but robust unit tests shouldn’t depend on state anyways. If you want to test state, use functional tests instead.


Form Validation vs Model Validation

This is a follow-up on Why I’m using a separate layer for input data validation that explains the key differences between client-side, input value (form) and model validation.

In general, model validation operates on trusted data (internal system state) and should ideally be repeatable at any point in time while input validation explicitly operates once on data that comes from untrusted sources (depending on the use case and user privileges).

This separation makes it possible to build reusable models, controllers and forms that can be loosely coupled through dependency injection:

class UserController
    protected $user;
    protected $form;

    public function __construct(User $user, UserForm $form)
        $this->user = $user;
        $this->form = $form;

    public function putAction($id, Request $request) // Update
        $this->user->find($id); // Find entity (throws exception, if not found)
        $this->form->setDefinedValues($this->user->getValues()); // Initialization
        $this->form->setDefinedWritableValues($request->request->all()); // Input values
        $this->form->validate(); // Validation

        if($this->form->isValid()) {
            $this->user->update($this->form->getValues()); // Update values
        } else {
            // Return first error (HTTP isn't designed to return multiple errors)
            throw new FormInvalidException($this->form->getFirstError());

        return $this->user->getValues(); // Return updated entity values

Think of input validation as whitelist validation (“accept known good”) and model validation as blacklist validation (“reject known bad”). Whitelist validation is more secure while blacklist validation prevents your model layer from being overly constrained to very specific use cases.

Invalid model data should always cause an exception to be thrown (otherwise the application can continue running without noticing the mistake) while invalid input values coming from external sources are not unexpected, but rather common (unless you got users that never make mistakes). Validation within a specific model may not be possible, if a set of input values must be validated together (because they depend on each other) but the individual values belong to different models – at least this can create additional dependencies between models that would not be there otherwise up to the point that all models depend on each other. In short: The application may still work as expected, but the code is a mess.

From a theoretical standpoint, any complex system has more internal state than it exposes to the outside, thus it is never sufficient to use model validation only – except the model provides two sets of methods: some that are used internally and some that can be exposed to arbitrary input data from any source. Aside from side-effects such as limited user feedback (exception messages) and bloated model code, this approach may easily lead to serious security flaws. Malicious input data is a much higher threat to multi-user Web applications than to classical single-user desktop applications. Simple blacklist model validation may be fully sufficient for desktop applications, which are in full control of the user interface (view layer).

Client-side (JavaScript or HTML) form validation is always just a convenience feature and not reliable. However, you can (at least partly) reuse existing server-side form validation rules to perform client-side validation, if they can be easily converted to JSON (for JavaScript) or be passed to template rendering engines such as Twig or Smarty (for HTML). Reusing model layer validation rules in a similar fashion is at least difficult, if not impossible.

See also:

Why I’m using a separate layer for input data validation

Validation in the MVC patternWhile some developers seem to prefer to implement their user data validation rules directly in the model layer (or even worse, the ORM entity layer), this very often leads to problems as described by Stefan Priebsch in his blog post on How to Validate Data.

In addition to the many issues he mentioned, you should consider the following advantages of using a separate layer to validate user input data:

  • While a certain minimum level of validation must be performed in the model and persistence layer for security reasons, many validation rules are high level and depend on the use case. For example, an admin user might have less strict validation rules than a regular user. In this case, the model would require the currently active user as a dependency to perform the validation, which adds unnecessary complexity. Even worse, the very same data might be valid or invalid, depending on whether it was loaded from the database (and stored there by the admin user) or if it is coming from the frontend and should be stored in the database by a regular user. I’ve seen code like this and it’s not fun to work with.
  • There are cases in which data validation rules for individual fields depend on each other, for example: If the email address is empty, you need to provide a phone number. If you’re working with exceptions and do the validation in individual setters, this doesn’t work well or at all.
  • Sometimes, you want to store invalid data with a dirty flag and fix the validation issues later. This might be the case, if you have to transfer values from a paper form and then call the customer later to complete missing fields.
  • More complex applications implement use-cases which store data in a number of different models at the same time. If validation is supposed to happen in the model layer, how do you decide which model is responsible?
  • Sharing validation rules between backend and frontend is much easier, if they can be serialized. This is not the case for explicit code in the model layer. Using plain arrays to describe validation rules and a separate form class that interprets them (at least partly), enables reuse in backend and frontend. True, that form class must be available in all applicable programming languages, but this can be solved and usually is much less work, than code duplication as the alternative solution.
  • There always comes the day, when you need to refactor or replace your model layer, for example when switching from database storage to a REST service. If your use-case related validation rules are not mixed with your model layer code, this will be much easier.

For semantic reasons, I call this additional validation layer the forms layer (see flow chart) in my own projects, but it really doesn’t matter. Just call it as you like, as long as you are able to leverage the advantage of using a separate validation layer. It helps a lot.

You’re welcome to check out my code on GitHub to see some practical examples:

Dependent Symfony 2 Bundles and Testability

dagdepsI just stumbled upon a question concerning Symfony 2 bundles and testability that I want to share with you.

When developing with Symfony, beginners tend to use lots of existing bundles, because this seems to be the recommend way of building an application. Later, they wonder, why it’s so hard to write component tests or they write functional tests instead and call them unit tests, because this really seems to be the only possible way to write tests.

Functional tests are not suitable for test driven development, slow and fragile.

Why are dependent bundles bad for testing?

Bundles are a Symfony specific way to share entire libraries incl. their respective dependency injection container configuration.

Therefore, bundles depend on the Symfony kernel and if one bundle depends on another bundle, you create heavy dependencies, which effectively prevents component testing: To test a component in bundle A, you’ll need bundle B plus the Symfony kernel. Of course you can mock every single dependency, but that’s an awful lot of work, you need to understand them first and you’ll end up with completely isolated unit tests, not component tests.

That’s netmikey’s problem description on Stackoverflow:

So it feels like we’re gonna end up needing a whole Symfony2 project in our bundle’s repository anyway in order to bootstrap the whole framework to be able to eventually test our components.

What are bundles good for?

Let me quote a great answer by Boris Guéry on Stackoverflow:

Most of the time, you will take much more time to “get it done” using community bundle than making your own (see Sonata bundles).

I don’t say they are bad bundles, not at all, but they deserve different purposes.

For me such bundles may help newcomers to have a quick implementation, to get things done, and in the case of a Rapid Application Development, it may be really easy to get a fully working application with all the registration process done.

But most of the time, you realize that using third party codes ties you too much to their own concept and that is wrong.

Bundles are certainly bad for testability, if there are any dependencies between bundles. They are good for effectively separating parts of an application, if there are no dependencies, e.g. running multiple individual applications on the same Symfony installation. It’s basically the opposite of thin server architecture and microservices. If you add enough bundles, you got a good chance of ending up with a fat, slow application who does about everything.

Ready-to-use bundles can be a starting point for new users and probably results in more configuration than actual coding. They are no foundation for fast and fully testable enterprise applications.

Getting rid of bundles

The good news is: You don’t really need bundles. Most of the time, they are just a convenience feature that saves you from setting up your own dependency injection configuration for external libraries. Instead you have to read the documentation to know how to configure them. I don’t really see the advantage, but maybe there is one.

If the class you want to test depends on classes in other bundles and you want to write unit / component tests, you have to understand the inner workings of those dependencies anyways. So why don’t understand them in the first place?

Let’s have a look at the Twig bundle. You can include it in the Symfony kernel like this:

public function registerBundles()
    $bundles = array(
        new Symfony\Bundle\TwigBundle\TwigBundle(),

    return $bundles;

What this code does is loading Symfony\Bundle\TwigBundle\TwigBundle.php via the composer autoloader. TwigBundle.php is then starting some hidden machinery built into the bundle to add parameters and services to your existing dependency injection container. Something you could have done yourself in a few lines of your own container configuration (e.g. parameters.yml and services.yml):

    twig.path: '%app.path%/../src/App/View'
        charset: 'UTF-8'
        debug: false
        strict_variables: false
        cache: '%app.cache_path%/twig'
        auto_reload: true

        class: Twig_Loader_Filesystem
        arguments: [ %twig.path% ]

        class: Twig_Environment
        arguments: [ @twig.loader, %twig.options% ]        

The difference is, this time you know what happens, with which classes you are actually working and how to mock them, if you need to. Also you don’t need a full featured Symfony kernel: Something lighter combined with the Symfony dependency injection will do as well. This is what I did when I combined Silex with the Symfony dependency injection container and called it Symlex. It almost feels like Symfony, but is much faster and fully testable. The downside is, you can not use bundles.

How to conduct a great IT job interview

If you own a software company or work there in HR, it is your goal to hire the best engineers for your business. So you certainly don’t want to mess up the recruitment process. As someone who’s in the industry for two decades (sitting on both sides of the table), I would like to share a few points about how to make an interview a positive and insightful experience for everyone.

© thedailyenglishshow

Answer questions

Don’t encourage the candidate to ask questions, if you’re not qualified or willing to answer them. It’s really frustrating to talk to someone who’s encouraging you to ask questions and every single time you get answers like: “Sorry, I can not answer that – I do not know the product in detail” or “We can answer that as soon as you start working here”. Do you expect your best candidates to ask self-answering questions? Great candidates are evaluating you, your company, and whether they really want to work for you.

Don’t pretend you’re doing the candidate a favour

If you really want the best engineers, say so (and pay them well). Don’t give the impression that the candidate might be at best a tiny addition to your already great team of engineers. Would you like to spend more time with a company, who doesn’t really need you than with your best friends and family? Full-time jobs are like that.

Don’t sell

Good engineers are usually not impressed by people who try to sell them something. They’re used to evaluate software tools and libraries on a daily basis without being dazzled by fancy marketing brochures. If your company built an awesome technology stack or has other unique offerings, say so – but provide credible evidence without being asked. It’s not credible, if you say you built the highest quality application framework and at the same time, your application is slow or contains obvious bugs. Engineers can notice those smells, which sometimes indicate deeper problems within the software or the organization.

Make the interview a conversation, not an interrogation

Nothing shows less respect towards an obviously experienced candidate than being forced to answer a huge list of “standard technical questions”. That might be alright for somebody coming straight from university, but even those candidates usually have a unique story to tell, if you let them. Just asking standard questions might also expose a severe lack of preparation on your side. How would you feel, if you built several database libraries and wrote magazine articles covering advanced SQL topics – and then being asked how a simple SQL join works? If an experienced database engineer was sitting in front of me, I would take the chance and start a conversation about actual issues we have to solve on the production servers. Maybe the candidate can provide a solution for free? Who knows.

Treat your candidates as unique individuals and find their strengths. If you do, they’ll open up, you can have a great conversation and you might even be able to learn from them. Don’t desperately try to find a question they can not answer. Don’t play the “I am smarter than you” game. Do you really want to hire an intimidated engineer based on “knowing” all weaknesses?

No good and focused engineer knows all the books, APIs and software libraries out there. Some of the best use intuitive problem-solving strategies, which they can not describe in words.

Take some time to prepare yourself

Before going into an interview, carefully read the candidates resume, thoroughly check her/his code on GitHub, read a few blog posts and maybe have a short chat with her/his references, so that you already got a first impression and something to start a conversation with.

The candidate will love you for that!

PHP and Zend Framework 2 are losing popularity

According to Google Trends and the personal feedback I get from the PHP developer community, Zend Framework 2 quickly lost it’s initial momentum while SensioLab’s micro-framework Silex is attracting more developers slowly but steadily.

If you already work with Symfony 2 and consider switching to Silex, you might want to have a look at Symlex: It’s based on Silex but uses the familiar Symfony dependency injection container instead of Pimple to combine the best of both worlds.

Another trend that can be observed is that PHP in general is losing popularity due to alternative technologies such as Node.js:

PHP vs JavaScript

Howto: Install PHP, PHPUnit and Composer on Mac OS X

Make sure the directories /usr/local, /usr/local/bin and /usr/local/sbin exist and check the permissions, so that regular users can access them. This should already be the case, if you got Homebrew installed and working.

Open ~/.bash_profile and check, if /usr/local/bin and /usr/local/sbin are properly added to your PATH environment variable:

export PATH="/usr/local/sbin:/usr/local/bin:$PATH"

If there is no ~/.bash_profile yet, simply create it (see Mac OS X configuration for software developers).

Since using Homebrew seems overly complicated and you’ll get an outdated version (5.6.9 instead of 5.6.14 as of writing this), I recommend installing the binary package provided by Liip – thank you!

These commands will install the latest release of PHP 5.6 to /usr/local/php5:

# curl -s | bash -s 5.6
# cd /usr/local/bin
# ln -s /usr/local/php5/bin/php php
# ln -s /usr/local/php5/bin/phpize phpize
# ln -s /usr/local/php5/bin/php-config php-config
# php -v
PHP 5.6.14 (cli) (built: Oct 2 2015 08:55:56)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2015, by Zend Technologies
with Xdebug v2.2.5, Copyright (c) 2002-2014, by Derick Rethans

If you prefer, you can choose to install other versions of PHP up to 7.0.

To download and install the current stable version of PHPUnit:

# wget
# chmod +x phpunit.phar
# mv phpunit.phar /usr/local/bin/phpunit
# phpunit --version
PHPUnit 5.0.8 by Sebastian Bergmann and contributors.

To download and install the latest version of composer:

# curl -sS | php
# chmod +x composer.phar
# mv composer.phar /usr/local/bin/composer
# composer -V
Composer version 1.0-dev (ef2856ef55715027ce2275f3b3bf1e84bfc778a4) 2015-10-29 22:35:30

Mac OS X configuration for software developers

Coming from Linux and FreeBSD, I initially didn’t feel comfortable working with OS X and I still think it’s a bad idea to run a full featured Web server on a Mac. But there are a couple of things you can do to turn your Mac into a great development environment.

Install the following essential software packages

Productivity Tools and IDEs

  • I strongly recommend using a JetBrains IDE such as PhpStorm, IntelliJ IDEA or PyCharm (~ 100 USD)
  • Snagit via App Store for creating nice screen shots (~ 50 USD)
  • Scroll Reverser, if you are working with a touch pad and a mouse (on a MacBook)
  • Transmit via App Store, if you need to work a lot with remote FTP, SFTP or WebDAV servers, e.g. in the printing industry (~ 50 USD)

Mouse & Touchpad

  • Get a mouse with 3 buttons – otherwise it won’t feel like a real Unix, especially if you try to copy & paste on the console. I’m very happy with the SteelSeries Sensei (~ 100 USD), but a cheap Logitech mouse for 9.99 will do as well.
  • If you also find it difficult to get used to Apple’s default mouse acceleration curve, try to install SteelSeries ExactMouse Tool (it doesn’t matter if you’re actually using a SteelSeries mouse)
  • Go to System Preferences -> Accessibility and disable “Shake mouse pointer to locate” (only applies to OS X 10.11 or later)
  • If you’re using Google Chrome, I strongly recommend disabling it’s two-finger back/forward navigation:
    defaults write AppleEnableSwipeNavigateWithScrolls -bool FALSE

Terminal Settings

  • Go to Terminal -> Preferences… -> Basic and change the colors to something more pleasant than black on white (see screenshot below)
  • Create the file ~/.bash_profile and add the following lines:
    alias ll='ls -alhG'
    export PS1="[\[\033[01;31m\]\u\[\033[01;33m\]@\[\033[01;36m\]\h \[\033[01;33m\]\w\[\033[01;35m\]\[\033[00m\]]# "
    export PATH="/usr/local/bin:$PATH"
    export COPYFILE_DISABLE=true

    This will add some color to your terminal and support for the ll alias (ls -alhG). COPYFILE_DISABLE prevents several of the system-supplied programs (including tar) from giving special meaning to ._* archive members.

Terminal_ColorsUI Settings

  • Move the Dock to the left hand side, so that you can use the full height of your screen for coding (Dock Preferences… -> Position on screen)
  • Go to System Preferences -> Notifications and reduce the amount of notifications as far as possible
  • Optionally: Disable all user interface animations, if you’re as easily distracted as I am

NFS & SMB Network Storage

Based on my experience, NFS works best for accessing the file systems of local virtual machines for development whereas SMB is best for regular network attached storage. If you really want to use NFS for shared network storage, be prepared to dive into the details of Unicode. Rsync users should install rsync 3 for the same reason: rsync 2 doesn’t support iconv Unicode conversion from OS X to Linux / Unix format – international characters will get corrupted otherwise.

Go to Finder -> Go -> Connect to server… to mount network drives. You can then add frequently used folders to your “Favorites” in Finder. They will be mounted on demand, whenever you access them.

It can be convenient to make the Volumes folder visible in Finder (it’s hidden by default):

sudo SetFile -a v /Volumes

You should disable the creation of Apple’s proprietary .DS_Store files on shared network volumes, if you don’t want to annoy other users:

defaults write DSDontWriteNetworkStores true

Don’t use the autoloader (/etc/auto_*) – it only causes trouble, as I had to find out the hard way. You’re lucky, if you never heard about it. Instead, add network drives to your Login Items, if you want to mount them automatically after login:


Final Actions

When you’re done, don’t forget to create SSH keys and to unlock git by running it once on the command-line (it will ask you to agree to Apple’s terms and conditions).

See also

Reducing the Software Value Gap

Research shows at least 50% of IT developers’ time is wasted due to the following reasons:

  • Rework due to incomplete or poorly defined needs and requirements (“incomplete kit”);
  • Rework due to frequent changes in requirements and scope up to the final delivery stages; most such changes are not “must have” but only “nice to have”;
  • Software solutions developed and delivered but eventually not used (happens all too often);
  • Over-specification of requirements to include functionality and features seldom or never applied; and
  • Having too many activities assigned to individual developers, leading to wasteful context switching among activities (bad multitasking).

Source: Communications of the ACM, Vol. 57 No. 5, Pages 80-87

Developer Conference 2013

Developer Conference 3013I’m not known for going to conferences very often, so this year I will do something very special: Attending two conferences! PHP Unconference in September was great fun already. The other one will be Developer Conference in Hamburg, which starts in two days. I know some of the speakers personally (the list is actually quite impressive) and I look forward to see them again. Even Professor Lutz Prechelt will give a talk. He’s head of the Software Engineering work group at Free University Berlin, right around the corner from where I live. The list of speakers also includes stars like Lars Jankowfsky (Mr Jet Set), Johann-Peter Hartmann (CTO of Mayflower) and Johannes Schlüter (PHP core developer).

Just attending the conference wouldn’t be enough this time. That’s why I decided to get the (inexpensive) blogger ticket and spam the world with my impressions and photos. The deal is to tweet a bit, write two blog posts and upload some photos.

Tickets are still available!

PS: The conference location is a movie theater, so in theory, you can watch all movies for free and also get free popcorn and soft drinks. Sounds too good to be true, doesn’t it?