Refactoring argument checking

Where I test exceptions because bad arguments happen.

Testing for the input

Sadly not all the input to a function or method can be type-hinted and implicitly checked for conformity.
Getting back to the WPSchedule_Schedule_Schedule class, the star of the wp-schedule show, I want to test that the method schedule will throw an Exception when the hook name is not a string or is an empty string; right now the method is not complicated at all

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 );
}

but, beside for time and interval type hinting, the $hook argument could be anything.
I've set up a test method and a corresponding test provider for the purpose

public function badHookArgs() {
    return [
        [ 23 ],
        [ '' ],
        [ array() ],
        [ new stdClass() ],
        [ null ]
    ];
}

/**
 * @test
 * it should fail if calling with wrong or missing args
 * @dataProvider badHookArgs
 */
public function it_should_fail_if_calling_with_wrong_or_missing_args( $badHookArg ) {
    $now = time();
    $time = FunctionMocker::replace( '\WPSchedule_Time_TimeInterface::getTime', $now );
    $interval = FunctionMocker::replace( '\WPSchedule_Interval_IntervalInterface::getInterval', 500 );

    $this->setExpectedException( '\Exception' );

    $this->sut->schedule( $time, $interval, $badHookArg );
} 

Where the test provider method will allow me to add tests at pleasure later should the need arise.
Without any check in place the tests will fail [hook argument checking tests failing](http://theaveragedev.local/wordpress/wp-content/uploads/2014/12/2014-12-18-at-18.15.png)

Evolving the argument check

First line of defense is adding a check for the $hook arg in the schedule method

    public function schedule( WPSchedule_Time_TimeInterface $activation_time, WPSchedule_Interval_IntervalInterface $recurrence_interval, $hook, array $args = null ) {
        if ( ! is_string( $hook ) || empty( $hook ) ) {
            throw new Exception( 'Hook name must be a non empty string' );
        }

        wp_schedule_event( $activation_time->getTime(), $recurrence_interval->getInterval(), $hook, $args );
    } 

and that will do it [hook argument checking tests passing](http://theaveragedev.local/wordpress/wp-content/uploads/2014/12/2014-12-18-at-18.19.png)

Refactoring

The following phase of TDD is refactoring and that I will do to keep code DRY; I will need to check for the $hook argument in any of the class methods accepting it as an argument and it makes sense to create a private method to check for the argument that current and future methods of the class will be able to use; simply moving code I add this method to the class

private function checkHook( $hook ){
    if ( ! is_string( $hook ) || empty( $hook ) ) {
        throw new Exception( 'Hook name must be a non empty string' );
    }
}

and will call it refactoring the schedule method

public function schedule( WPSchedule_Time_TimeInterface $activation_time, WPSchedule_Interval_IntervalInterface $recurrence_interval, $hook, array $args = null ) {
    $this->checkHook($hook);

    wp_schedule_event( $activation_time->getTime(), $recurrence_interval->getInterval(), $hook, $args );
}

Good laziness

A good thing about TDD is that it makes me lazy: to write code I have to test it so the more code I write the more I have to write tests.
I don't want to write more tests that's needed.
Refactoring the argument checking into a method of its own allows me to test the whole class code, "cover it", without having to test that any method accepting an $hook argument throws if an invalid $hook argument is passed to the method: I just need to test it in one place.
Do I really need to test such trivial code? Probably not right now but might need to do it in the future as the class evolves and the $hook parameter becomes more complex and contextual: in that occurrence I will just need to modify/update the code in one place.

Even more laziness

The version of the project that's on GitHub testifies to my laziness as a TDDer even more: I've developed an argument checking utility class that's PHP 5.2 compatible and that I'm using to make the checks.
The checkHook method evolves to

private function checkHook( $hook ) {
    Arg::_( $hook, "Hook name" )->is_string()
       ->assert( ! empty( $hook ), 'Hook name must be a non empty string' );
} 

Which will give the caller a more precise exception.
Why that? Because that class is tested already and I know it will work as intended. Same concept as before, just worse.

Next

Time to wrap up the wp-schedule package.