147 votes

PHPUnit: affirmer que deux ensembles sont égaux, mais l'ordre des éléments n'est pas important

Ce qui est un bon moyen pour affirmer que les deux tableaux d'objets sont égaux, où l'ordre des éléments dans le tableau est sans importance, ou même des sujets à changement?

41voto

Craig Points 333

La façon la plus propre de le faire serait d'étendre phpunit avec une nouvelle affirmation de la méthode. Mais voici une idée pour un moyen plus simple pour l'instant. Code non testé, veuillez vérifier:

Quelque part dans votre application:

 /**
 * Determine if two associative arrays are similar
 *
 * Both arrays must have the same indexes with identical values
 * without respect to key ordering 
 * 
 * @param array $a
 * @param array $b
 * @return bool
 */
function arrays_are_similar($a, $b) {
  // if the indexes don't match, return immediately
  if (count(array_diff_assoc($a, $b))) {
    return false;
  }
  // we know that the indexes, but maybe not values, match.
  // compare the values between the two arrays
  foreach($a as $k => $v) {
    if ($v !== $b[$k]) {
      return false;
    }
  }
  // we have identical indexes, and no unequal values
  return true;
}

Dans votre test:

$this->assertTrue(arrays_are_similar($foo, $bar));

36voto

Valentin Despa Points 3540

Mon problème est que j'ai 2 tableaux (array touches ne sont pas pertinentes pour moi, juste les valeurs).

Par exemple, j'ai voulu tester si

$expected = array("0" => "green", "2" => "red", "5" => "blue", "9" => "pink");

avait le même contenu (afin de ne pas pertinente pour moi)

$actual = array("0" => "pink", "1" => "green", "3" => "yellow", "red", "blue");

J'ai donc utilisé array_diff.

Résultat Final a été (si les matrices sont égales, la différence de résultat dans un tableau vide). Veuillez noter que l'écart est calculé de deux façons (Merci @béret, @GordonM)

$this->assertEmpty(array_merge(array_diff($expected, $actual), array_diff($actual, $expected)));

Pour un message d'erreur plus détaillé (en cours de débogage), vous pouvez également tester comme cela (merci @DenilsonSá):

$this->assertSame(array_diff($expected, $actual), array_diff($actual, $expected));

Ancienne version avec des bugs à l'intérieur:

$this->assertEmpty(array_diff($array2, $array1));

23voto

rodrigo-silveira Points 2225

Une autre possibilité:

  1. Trier les deux tableaux
  2. Convertir une chaîne de caractères
  3. Affirmer que les deux chaînes sont égales

$arr = array(23, 42, 108);
$exp = array(42, 23, 108);

sort($arr);
sort($exp);

$this->assertEquals(json_encode($exp), json_encode($arr));

15voto

radioheaded Points 31

Simple méthode d'assistance

protected function assertEqualsArrays($expected, $actual, $message) {
    $this->assertTrue(count($expected) == count(array_intersect($expected, $actual)), $message);
}

Ou si vous avez besoin de plus d'informations de débogage lorsque les tableaux ne sont pas égaux

protected function assertEqualsArrays($expected, $actual, $message) {
    sort($expected);
    sort($actual);

    $this->assertEquals($expected, $actual, $message);
}

8voto

Rodney Gitzel Points 1763

Si le tableau est triable, je voudrais trier fois avant de vérifier l'égalité. Si non, je voudrais les convertir en des ensembles, de la sorte, et de comparer ces.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X