1

I'm looking for solution to test an array of objects with PHPUnit in my Laravel project.

This is my haystack array:

[
    [
        "id" => 10,
        "name" => "Ten"
    ],
    [
        "id" => 5,
        "name" => "Five"
    ]
]

And this is the needles array:

[
    [
        "id" => 5,
        "name" => "Five"
    ],
    [
        "id" => 10,
        "name" => "Ten"
    ]
]

The order of objects doesn't matter, also keys of objects doesn't matter. The only matter is we have two objects and all objects has exactly same keys and exactly same values.

What is the correct solution for this?

matiaslauriti
  • 7,065
  • 4
  • 31
  • 43
netdjw
  • 5,419
  • 21
  • 88
  • 162

2 Answers2

1

You can do this using the assertContainsEquals method like this:

$haystack = [
    [
        'id' => 10,
        'name' => 'Ten'
    ],
    [
        'id' => 5,
        'name' => 'Five'
    ]
];

$needles = [
    [
        'name' => 'Five',
        'id' => 5
    ],
    [
        'id' => 10,
        'name' => 'Ten'
    ]
];

foreach ($needles as $needle) {
    $this->assertContainsEquals($needle, $haystack);
}

You could also a create your own assert method if you intend to perform the assertion more often:

public function assertContainsEqualsAll(array $needles, array $haystack): void
{
    foreach ($needles as $needle) {
        $this->assertContainsEquals($needle, $haystack);
    }
}
Roj Vroemen
  • 1,853
  • 12
  • 11
  • This is a good answer, but if I think right, it will give true if the haystack contains other elements too, right? – netdjw May 17 '22 at 13:14
  • No, as soon as you add another key to either the haystack or one of the needles it will fail – Roj Vroemen May 17 '22 at 13:29
0

Based on @Roj Vroemen's answer I implemented this solution for exact match asserting:

    public function assertArrayContainsEqualsOnly(array $needles, array $haystack, string $context = ''): void
    {
        foreach ($needles as $index => $needle) {
            $this->assertContainsEquals(
                $needle,
                $haystack,
                ($context ? $context . ': ' : '') . 'Object not found in array.'
            );

            unset($haystack[$index]);
        }

        $this->assertEmpty(
            $haystack,
            ($context ? $context . ': ' : '') . 'Not exact match objects in array.'
        );
    }
netdjw
  • 5,419
  • 21
  • 88
  • 162