Unit Testing Tutorial Part V: Mock Methods and Overriding Constructors

Previously in my PHPUnit tutorial series, you learned about the very powerful concept of mock objects and stub methods. This concept is central to successful unit testing, and once it fully ‘clicks’ in your head you will start to realize how useful and simple testing can be.

There is also another thing I want to make clear: creating tests is basically a puzzle - you simply have to go step by step, making sure all the pieces fit together correctly so you can get your green. I hope to make clear what I mean by the end of this tutorial.

INTRODUCING MOCK METHODS

In my previous tutorial you learned all about mock objects and stub methods. There is another very similar concept you must also know about: mock methods.

To recap:

Mock Object

A mock object is an object that you would create using PHPUnit’s getMockBuilder() method. It is basically an object that extends the class you define and allows you to perform nifty tricks and assertions on it.

Stub Method

A stub method is a method contained within a mock object that returns null by default, but allows you to easily override the return value.

Mock Method

A mock method is pretty simple - it does the exact same thing its original method would. In other words any code that is in the method you are mocking will actually run and will not return null by default (unless that is what it originally did).

Mark Nichols gives a very good explanation of what the difference between mock and stub methods are.

Basically mock methods are useful for when you want the code inside of it to run, but also want to do some assertions on the behavior of the method. These assertions could be that specific parameters are passed to the method (if it applies), or that the method is called exactly 3 times or not at all.

Do not worry if this does not make immediate sense yet.

Continue reading


Unit Testing Tutorial Part IV: Mock Objects, Stub Methods and Dependency Injection

In my previous articles, I have brought you up to speed with writing basic tests for basic methods. You are now able to use the @dataProvider annotation, generate coverage reports, and how to use a few select assertions.

So far we have written tests for simple, straight-forward methods. Maybe a call to an internal method inside the same class, even an if block thrown in for good measure, but nothing at all complex.

While this is great for learning, in the real world you will rarely come across something as simple as what you have encountered so far. What you will usually see are methods that instantiate other class objects, call methods within the same class, use statics, or have foreign object dependencies injected via parameters.

PAYMENT CLASS

Today I will showcase more advanced testing concepts using code we are all familiar with and may have used in the past: the payment processor API. Specifically for Authorize.net, but just as easily could be any processor API.

Grab the authorize.net files

First, update your ./composer.json file with the following:

{
    "require": {
        "ajbdev/authorizenet-php-api": "dev-master"
    },
    "require-dev": {
        "phpunit/phpunit": "3.7.14"
    },
    "autoload": {
        "psr-0": {
            "phpUnitTutorial": ""
        }
    }
}

We are simply adding in an unofficial Authorize.net entry to grab all the files.

To install, run ./composer.phar update.

Continue reading


Unit Testing Tutorial Part III: Testing Protected/Private Methods, Coverage Reports and CRAP

This is Part III of a multi-part series. Below are the links to other parts of this tutorial!

A common question I keep hearing repeated is, “How much do I test?”.

A common response is, “Until you have 100% code coverage.”.

In this third part of my unit testing tutorial, I will explain what code coverage is and why 100% of it may not be what you should aim for.

But first, how to test your private/protected methods!

PROTECTED/PRIVATE METHOD TESTING

If you look at the second part of this series, you will notice that we instantiate our class to be tested via a regular new call. You may also be left wondering how to test protected or private methods if you are unable to access them directly via the instantiated object ( $url->someProtectedMethod() ).

Usually the answer would be, “You do not test protected/private methods directly.”. Since anything non-public is only accessible within the scope of the class, we assume that your class’s public methods (its API) will interact with them, so in the end you are actually indirectly testing these methods anyway.

Of course, there are always exceptions to the rule: What if you are testing an abstract class that defines a protected methods but does not actually interact with it?

What if you want to test different scenarios for a particular method and do not have the opportunity to go through your public methods?

I will explain the process!

Continue reading


Unit Testing Tutorial Part II: Assertions, Writing a Useful Test and @dataProvider

In the first part of this series, I walked you through initial installation and configuration of PHPUnit for a new project. I showed you some conventions that PHPUnit expects, and even walked you through creating a simple, stupid, and seemingly useless test.

It did, however, introduce you to the most basic assertion PHPUnit ships with - assertTrue().

ASSERTIONS

What is an assertion?

Wikipedia defines an assertion as

a predicate (a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place.

Translated, all it is saying is that an assertion verifies a statement made equals true.

Assertions evaluate to true

In our initial example,

public function testTrueIsTrue()
{
    $foo = true;
    $this->assertTrue($foo);
}

we asserted that true will assert to true ( if (true == true) ). There is no magic here, what you see is what you get with assertions.

If we assert that false is true ( if (false == true) ), we would get a failing test:

public function testTrueIsTrue()
{
    $foo = false;
    $this->assertTrue($foo);
}

What if we wanted to assert that false is false ( if (false == false) )?

public function testFalseIsFalse()
{
    $foo = false;
    $this->assertFalse($foo);
}

This test would pass because our assertion would be true, even if the assert method is called assertFalse().

Available assertions

PHPUnit ships with 90 assertions, which are listed here. If you use a proper IDE, you will not need to memorize any of them, as they are accessible through $this->assert*. You also do not need to use them all. Most of the time you will only use assertArrayHasKey(), assertEquals(), assertFalse(), assertSame() and assertTrue(). I do not think I have ever used more than 15% of all available assertions in the time I have tested my code, so moving forward I will focus mostly on these five assertion methods and maybe lightly showcase a few others.

Custom assertions

PHPUnit assertion methods are just that - regular methods that return either true or false after evaluating the code you have passed. If you cannot find an assertion to perfectly match your requirement, creating a new one is as simple as creating a new method! There is no complicated plugin architecture to learn - just define the method in your test class and start using it. If you ever need it in more than one class, move it to a parent class all your tests extend.

I will go through this in more detail in the future.

Continue reading


Unit Testing Tutorial Part I: Introduction to PHPUnit

For months now I have been telling myself I would create an in-depth, multi-part series of articles that would take a developer from being a complete newbie at testing to have them mocking classes left and right and asserting until the break of dawn.

This series will introduce you to the core concepts of testing. It will tell you why statics are bad, why dependency injection is king, what the difference between a mock and a stub is and how to love the red and green bar.

I will lightly touch on test-driven development but will not focus on it as I believe writing your code to be testable and learning how to actually test is a big enough challenge to learn at first without throwing in a completely different method to your development process. Baby steps is the name of the game.

What this series will not go over is why you should test, why testing is good and the benefits of testing, other than a slight glossing over.

If you would like to be serenaded with the virtues of testing then I recommend you check out the book Real-World Solutions for Developing High-Quality PHP Frameworks and Applications by Sebastian Bergmann and check out my buddy Chris Hartjes, The Grumpy Programmer’s blog. Chris has been screaming at the PHP community for years that they should test. He is now holding classes to teach you some knowledge and I wholeheartedly recommend you take a good look.

BEFORE YOU BEGIN

This series will assume you have a proper development environment set up. I highly recommend using a VM that mimics a server environment instead of having your server running alongside your daily OS. If you do not have a proper environment set up then I recommend you read through my Setting Up a Debian VM, Step by Step guide to get you up and running painlessly.

We are also going to use the command line to run … commands. If you are used to a GUI doing everything for you, it is high time you cowboy up and got to loving the terminal.

Continue reading