Instance method replacement with function-mocker

Picking up from where I had left and moving on with instance method replacement using function-mocker.

Mocking instance methods

Also known as test doubles that’s really the bread and butter of TDD and a possibility function-mocker does cover.
I want to test the WPSchedule_Schedule_Schedule::schedule method and its signature tells it depends on two other objects as dependencies:

    /**
     * Schedules an event.
     *
     * @param WPSchedule_Schedule_TimeInterface     $activation_time
     * @param WPSchedule_Interval_IntervalInterface $recurrence_interval
     * @param string                                $hook
     * @param array                                 $args
     *
     * @throws Exception
     * @return mixed
     */
    public function schedule( WPSchedule_Schedule_TimeInterface $activation_time, WPSchedule_Interval_IntervalInterface $recurrence_interval, $hook, array $args = null );

Which means I will have to mock both the WPSchedule_Schedule_TimeInterface and the WPSchedule_Interval_IntervalInterface interfaces.
Being function-mocker built on top of PHPUnit mocking interfaces is not an issue once those are defined.

The two interfaces

Sticking to the idea of coding as little as possible to pass the test once again I will write code I’m allowed to write laying down the two interfaces above while keeping the probable destination code in mind.
The WPSchedule_Schedule_Schedule::schedule method will call, in turn, a function WordPress defines and that’s

wp_schedule_event($timestamp, $recurrence, $hook, $args);

The arguments are pretty self-explanatory and will help me shape the two interfaces at hand that will have to supply the $timestamp and the $recurrence parameters.
Those fall in the field of the Strategy pattern and I’ll be delving into the usefulness of this in a next post; suffice to say I will define, by now, just one method for each

interface WPSchedule_Schedule_TimeInterface {

    /**
     * Returns a Unix timestamp.
     *
     * @return int
     */
    public function getTime();
}

interface WPSchedule_Schedule_IntervalInterface {

    /**
     * Returns a time interval in seconds.
     *
     * @return int
     */
    public function getInterval();
}

and will move to testing.

A first test

I will start by writing a failing test for the WPSchedule_Schedule_Schedule::schedule method setting up and replacing the two interfaces and the function above as needed

/**
 * @test
 * it should properly call wp_schedule_event with given parameters
 */
public function it_should_properly_call_wp_schedule_event_with_given_parameters() {
    $now = time();
    $time = FunctionMocker::replace('\WPSchedule_Time_TimeInterface::getTime', $now);
    $interval = FunctionMocker::replace('\WPSchedule_Interval_IntervalInterface::getInterval', 500);
    $wp_schedule_event = FunctionMocker::replace('wp_schedule_event', true);

    $this->sut->schedule($time, $interval, 'some_hook');

    $wp_schedule_event->wasCalledWithOnce([$now, 500, 'some_hook', null]);
} 

Reading the test line by line

$now = time();
$time = FunctionMocker::replace('\WPSchedule_Time_TimeInterface::getTime', $now);

I replace the WPSchedule_Time_TimeInterface::getTime method getting a $time replacement object in return; again in the following line

$interval = FunctionMocker::replace('\WPSchedule_Interval_IntervalInterface::getInterval', 500);

I replace the WPSchedule_Interval_IntervalInterface::getInterval method and get an $interval replacement object in return; both this and the $time one I will inject as dependencies in the method under test.

$wp_schedule_event = FunctionMocker::replace('wp_schedule_event', true);

I get a spy on the the wp_schedule_event function and make it return true when called;

$this->sut->schedule($time, $interval, 'some_hook');

I inject the replaced dependencies in the method and run it.
After it ran I check for the expectation on the wp_schedule_event function to be fulfilled and, on the first pass, will get a failing test
schedule first test fail

Passing the test

Implementing the code needed to pass this first test will require very little code to be written

public function schedule( WPSchedule_Time_TimeInterface $activation_time, WPSchedule_Interval_IntervalInterface $recurrence_interval, $hook, array $args = null ) {
    wp_schedule_event( $activation_time->getTime(), $recurrence_interval->getInterval(), $hook, $args );
}

schedule test pass
As usual the code can be found on GitHub tagged 0.1.4.

Next

I will move on exploring the possibility function-mocker offers for properly TDD code to be written in WordPress (WordPress not being the only case) while relying on its core principles and mechanisms.

I appreciate your input