php – Does PHPUnit have some inbuilt recursive array comparison function?-ThrowExceptions

Exception or error:

Some of the testing I will need to do will require comparing a known array with the result I am getting from the functions I will be running.

For comparing arrays recursively:

  • Does PHPUnit have an inbuilt function?
  • Does someone here have some code they have constructed to share?
  • Will this be something I will have to construct on my own?
How to solve:

Yes it does. assertEquals() and assertNotEquals() documentation.

Specifically:

assertEquals()

assertEquals(mixed $expected, mixed $actual[, string $message = ''])

Reports an error identified by $message if the two variables $expected and $actual are not equal.

assertNotEquals() is the inverse of this assertion and takes the same arguments.

Test Code:

public function testArraysEqual() {
    $arr1 = array( 'hello' => 'a', 'goodbye' => 'b');
    $arr2 = array( 'hello' => 'a', 'goodbye' => 'b');

    $this->assertEquals($arr1, $arr2);
}

public function testArraysNotEqual() {
    $arr1 = array( 'hello' => 'a', 'goodbye' => 'b');
    $arr2 = array( 'hello' => 'b', 'goodbye' => 'a');

    $this->assertNotEquals($arr1, $arr2);
}

[EDIT]

Here is the code for out of order aLists:

public function testArraysEqualReverse() {
    $arr1 = array( 'hello' => 'a', 'goodbye' => 'b');
    $arr2 = array( 'goodbye' => 'b', 'hello' => 'a');

    $this->assertEquals($arr1, $arr2);
}

This test fails:

public function testArraysOutOfOrderEqual() {
    $arr1 = array( 'a', 'b');
    $arr2 = array( 'b', 'a');

    $this->assertEquals($arr1, $arr2);
}

With message:

Failed asserting that 
Array
(
    [0] => b
    [1] => a
)
 is equal to 
Array
(
    [0] => a
    [1] => b
)

Answer:

@wilmoore

$array1 = array('hi','hi2');
$array2 = array('hi2','hi');
$this->assertEquals(array_values($array1), array_values($array2));

Will fail.

@Ben Dauphinee

It might be worth looking at assertContains(mixed $needle, array $haystack) but you would have to loop through both arrays and compare each element with the other array to ensure it contained all the required elements and no others, this however wouldn’t account for an array containing two identical elements

$array1 = array('hi','hi2','hi');
$array2 = array('hi2','hi');

would pass in this case

It also doesn’t account for any further recursion which would probably be quite complicated to deal with.

Depending on the complexity might just be easier in the long run to implement your own assert function.

Answer:

The assertEqual method head looks like this:

public static function assertEquals($expected, $actual, $message = '', $delta = 0, $maxDepth = 10, $canonicalize = FALSE, $ignoreCase = FALSE)

If the canonicalize parameter is set to true the arrays will be run through sort() first, this is usable if the keys are arbitrary and only the values matters.

However after looking over the array comparator code, the assertEqual actually does not care about the order of an associated array 🙂 It will simply look for the expected key in the result array, and then compare the values of those keys.

Answer:

I had this problem with some generated arrays with keys – I ended up passing both the expected array and the array being tested through ksort before calling assertEquals. This doesn’t work on recursive arrays, though.

$expectedArray = array('foo' => 1, 'bar' => 0);
$array = array('bar' => 0, 'foo' => 1);

ksort($expectedArray);
ksort($array);

var_dump($expectedArray); // outputs array('bar' => 0, 'foo' => 1);
var_dump($array); // outputs array('bar' => 0, 'foo' => 1);

$this->assertEquals($expectedArray, $array); // passes

Answer:

Sometime I do it like this:

$arrayResult = [....];
$arrayExpected = [....];

ksort($arrayResult); // or sort() for associative arrays
ksort($arrayExpected); 

self::assertSame($arrayExpected, $arrayResult);

Leave a Reply

Your email address will not be published. Required fields are marked *