PHPUnit: espera uma chamada de método com matriz como argumento

Eu tenho um caso de teste PHPUnit, no qual eu estou intrigado com o seguinte trecho. Quero verificar se o método actionUpload chama a function exponeAndSaveDataLines corretamente, ou seja, o primeiro argumento é uma matriz como espero que seja.

 public function test_actionUpload() { $sut = $this->getMockBuilder('MasterdataController') ->setMethods(array('exposeAndSaveDataLines', 'render')) ->disableOriginalConstructor() ->getMock(); $expectedLines = require_once ($this->dataDir . 'expectedLines.php'); $sut->expects($this->once()) ->method('exposeAndSaveDataLines') ->with($this->equalTo($expectedLines), $this->anything(), $this->anything(), $this->anything(), $this->anything()); $sut->actionUpload(); } 

O dado esperado é uma impressão da matriz atual, feita com um print_r (var_export($lines)) temporário print_r (var_export($lines)) no código real. Eu devolvê-lo no arquivo expectedLines.php , e quando eu imprimi-lo manualmente, está correto.

Agora, quando eu executo o caso de teste com um único personagem deliberadamente incorreto nas linhas expectedLines , recebo o seguinte erro (como esperado).

 Failed asserting that two arrays are equal. --- Expected +++ Actual @@ @@ 3 => 'Colour Group Code' - 4 => '{2F30E832-D3DB-447E-B733-7BC5125CBCCc}' + 4 => '{2F30E832-D3DB-447E-B733-7BC5125CBCCC}' ) ) ) 

No entanto, quando eu corrigir o erro, ele ainda menciona que os dois arrays não são iguais. No entanto, ele agora imprime toda a matriz (pelo menos o início dela, é uma matriz longa), mas não mostra nenhuma diferença (não – e + na frente de qualquer linha). Por que o método de expects não reconhece que os dois arrays são os mesmos? Como eu posso testar isso corretamente?

EDITAR 1

Eu abaixei a matriz, de modo que imprima toda a matriz quando eles não são iguais. Ainda não + ou – sinais na comparação.

Este é o fim do meu arquivo PHP de expectativa.

  'RetTarget Area' => array( 0 => array( 0 => '', 1 => '', 2 => '{C19D52BC-834C-45DA-B17F-74D73A2EC0BB} ' ), 1 => array( 0 => '1', 1 => '1', 2 => '{5E25C44F-C18A-4F54-B6B1-248955A82E59}' ) ) ); 

Este é o final da minha saída de comparação no console.

  'RetTarget Area' => Array ( 0 => Array ( 0 => '' 1 => '' 2 => '{C19D52BC-834C-45DA-B17F-74D73A2EC0BB} ' ) 1 => Array (...) ) ) 

Eu acho suspeito que a última Array não seja totalmente mostrada na comparação.

EDITAR 2

Acho que a ordem dos arrays é importante. Tenho certeza de que tenho todos os elementos na mesma ordem, se o PHP não estiver fazendo algo secreto sob o capô. A solução mencionada lá não consigo copiar, já que não tenho $this->assertEquals mas uma ->with($this->equalTo syntax.

EDITAR 3

Eu leio aqui sobre um parâmetro indocumentado $canonicalize que ordenamentos de ordens antes de comparar. Quando eu uso isso assim:

 $sut->expects($this->once()) ->method('exposeAndSaveDataLines') ->with($this->equalTo($expectedLines, $delta = 0.0, $maxDepth = 10, $canonicalize = true, $ignoreCase = false), $this->anything(), $this->anything(), $this->anything(), $this->anything()); 

Vejo que a ordem dos arrays é realmente alterada, mas ainda vejo o mesmo erro. Além disso, ainda uma matriz é “colapsada”, que eu suspeito que provoca essa falha. Além disso, não quero encomendar todas as minhas subarquetas, elas devem estar na mesma ordem no resultado real e esperado.

 --- Expected +++ Actual @@ @@ Array ( 0 => Array ( 0 => Array ( 0 => '' 1 => '' 2 => '{C19D52BC-834C-45DA-B17F-74D73A2EC0BB} ' ) 1 => Array (...) ) 

EDITAR 4

Quando eu uso identicalTo vez de equalTo , eu recebo uma mensagem de erro mais elaborada, dizendo que a única matriz não é idêntica à outra matriz, enquanto imprime ambas. Eu copi-colou-os em um arquivo de texto e usei o comando diff para verificar se há diferenças, mas não havia nenhum. Ainda assim, o PHPUnit afirma que os dois arrays não são iguais / idênticos.

EDITAR 5

Quando eu uso greaterThanOrEqual ou mesmo greaterThan vez de equalTo , então o teste passa. Isso não acontece por menos lessThanOrEqual . Isso implica que há uma diferença entre os dois arrays.

Se eu alterar manualmente o resultado esperado em algo com uma seqüência de caracteres que é alfabeticamente antes da seqüência de caracteres correta, eu também posso passar também, mas, claro, greaterThanOrEqual que o greaterThanOrEqual falha.

EDITAR 6

Estou convencido de que o fim da linha das strings na minha matriz está fazendo com que essa comparação falhe, o que não aparece em todas as comparações.

Agora tenho a seguinte afirmação.

 public function test_actionUpload_v10MasterdataFile() { .... $sut->expects($this->once()) ->method('exposeAndSaveDataLines') ->will($this->returnCallback(function($lines) { $expectedLines = include ($this->dataDir . 'ExpectedLines.php'); $arrays_similar = $this->similar_arrays($lines, $expectedLines); PHPUnit_Framework_Assert::assertTrue($arrays_similar); })); $sut->actionUpload(); } private function similar_arrays($a, $b) { if(is_array($a) && is_array($b)) { if(count(array_diff(array_keys($a), array_keys($b))) > 0) { print_r(array_diff(array_keys($a), array_keys($b))); return false; } foreach($a as $k => $v) { if(!$this->similar_arrays($v, $b[$k])) { return false; } } return true; } else { if ($a !== $b) { print_r(PHP_EOL . 'A: '. $a. PHP_EOL . 'Type: ' . gettype($a) . PHP_EOL); print_r(PHP_EOL . 'B: '. $b. PHP_EOL . 'Type: ' . gettype($b) . PHP_EOL); } return $a === $b; } } 

Com o seguinte resultado.

 A: {72C2F175-9F50-4C9C-AF82-9E3FB875EA82} Type: string B: {72C2F175-9F50-4C9C-AF82-9E3FB875EA82} Type: string 

Eu finalmente consegui o trabalho, embora seja um pouco de compromisso. Agora estou removendo novas linhas antes de comparar os arrays. Isso não pode ser feito with método, então eu fiz a seguinte construção.

 public function test_actionUpload_v10MasterdataFile() { /* * Create a stub to disable the original constructor. * Exposing data and rendering are stubbed. * All other methods behave exactly the same as in the real Controller. */ $sut = $this->getMockBuilder('MasterdataController') ->setMethods(array('exposeAndSaveDataLines', 'render')) ->disableOriginalConstructor() ->getMock(); $sut->expects($this->once()) ->method('exposeAndSaveDataLines') ->will($this->returnCallback(function($lines) { $expectedLines = include ($this->dataDir . 'ExpectedLines.php'); PHPUnit_Framework_Assert::assertTrue($this->similar_arrays($lines, $expectedLines)); })); // Execute the test $sut->actionUpload(); } ... private function similar_arrays($a, $b) { /** * Check if two arrays have equal keys and values associated with it, without * looking at order of elements, and discarding newlines. */ if(is_array($a) && is_array($b)) { if(count(array_diff(array_keys($a), array_keys($b))) > 0) { return false; } foreach($a as $k => $v) { if(!$this->similar_arrays($v, $b[$k])) { return false; } } return true; } else { $a = rtrim($a); $b = rtrim($b); $extended_output = false; if ($extended_output && ($a !== $b)) { print_r(PHP_EOL . 'A: '. $a. PHP_EOL . 'Type: ' . gettype($a) . PHP_EOL); print_r(PHP_EOL . 'B: '. $b. PHP_EOL . 'Type: ' . gettype($b) . PHP_EOL); } return $a === $b; } }