Markus Malkusch's weblog 

Mocking a built-in PHP function e.g. time()

by Markus Malkusch


Posted on Sunday Dec 07, 2014 at 03:59PM in Technology


When it comes to writing unit tests you sometimes want to mock a built-in function like time(). These libraries do exist:

I extend this list with the library PHP-Mock. PHP-Mock doesn't need any further extension. It uses PHP's namespace fallback policy:

For functions […], PHP will fall back to global functions […] if a namespaced function […] does not exist.

There exist plenty of resources which explain this technique in greater detail. This short example illustrates mocking an unqualified call to time() in the namespace foo:

namespace foo;

function time() {
    return 1234;
}

assert(1234 == time());

During developing and using PHP-Mock I experienced a suprising restriction which I documented in bug #68541:

Class methods do resolve unqualified function calls only once in their life time.

This means that the mocked function must be defined before the first call of a class method which would call the unqualified built-in function. Most of the times this restriction doesn't bother because a typical test would define the mock before calling the tested method. This piece of code illustrates the restriction:

namespace foo;

class Foo
{
    
    public static function time()
    {
        return time();
    }
}

Foo::time(); // If you remove this line all assertions are true.

// It doesn't matter if you eval the namespaced function or include it.
eval("
    namespace foo {
        function time() {
            return 1234;
        }
    }
");

assert (1234 == time());
assert (1234 == Foo::time()); // This assertion fails, Foo::time() calls \time()!



No one has commented yet.

Leave a Comment

HTML Syntax: Ausgeschaltet