Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best Practices for Data Providing - PHPUnit

Tags:

php

phpunit

I'm currently writing units tests for a library, after refactoring business logic from the data, I'm now in a bit of confused state over how to now test the logic!

For example, I have a quite complex process which an array of data get's passed through, I'm going to use a data provider for this so I can make sure it will work for all sorts of cases.

With the data that I'm going to be passing in through the data provider, should I also be passing an expected outcome? Or should this be calculated in the test.

As said, the process for the calculating is quite a complicated process, not quite $a + $b.

like image 358
Ben Avatar asked Oct 11 '12 09:10

Ben


2 Answers

To extend Steven's example, it can sometimes be helpful to provide a name for each data set. When one fails, PHPUnit will display its name rather than "data #0" in the failure message.

public static function GetRemoteAddressFromWebServerDataProvider()
{
    return array(
        'not forwarded' => array('127.0.0.1',  NULL,           '127.0.0.1'),
        'no remote address' => array('127.0.0.1',  '127.0.0.1',    NULL),
    );
}
like image 148
David Harkness Avatar answered Oct 21 '22 02:10

David Harkness


With data providers, I also provide the expected result. As I want the method to take the inputs and return a value, I do not want to implement the calculation twice, as 1 of the implementations may have an error.

I am not looking to use a mock since I am actually testing the methods/functions in question.

If we are calculating something based on 4 parameters, then my data provider will pass 5. The first parameter is the expected result, followed by the parameters to be passed to the method/function.

From this, my call is pretty straight forward:

public static function GetRemoteAddressFromWebServerDataProvider()
{
    return array(
        array('127.0.0.1',  NULL,           '127.0.0.1'),
        array('127.0.0.1',  '127.0.0.1',    NULL),
        );
}

/**
 * @dataProvider GetRemoteAddressFromWebServerDataProvider
 */
public function testGetRemoteAddressFromWebServer($Result, $HTTPXSetting, $RemoteAddress)
{
    $_SERVER['HTTP_X_FORWARDED_FOR'] = $HTTPXSetting;
    $_SERVER['REMOTE_ADDR']          = $RemoteAddress;
    $this->assertEquals($Result, GetRemoteAddressFromWebServer());
}
like image 22
Steven Scott Avatar answered Oct 21 '22 02:10

Steven Scott