PHPUnit的:用数组作为参数预期的方法调用 [英] PHPUnit: expect method call with array as argument
问题描述
我有一个PHPUnit的测试案例,其中我对下面的代码片段不解。我要检查,该方法 actionUpload
调用函数exposeAndSaveDataLines正确的,即第一个参数是一个数组,因为我希望它是。
公共职能test_actionUpload()
{
$ SUT = $这个 - > getMockBuilder('MasterdataController')
- > setMethods(阵列('exposeAndSaveDataLines','渲染'))
- > disableOriginalConstructor()
- > getMock(); $ expectedLines = require_once($这个 - > DATADIRexpectedLines.php'); $ sut->预计($这个 - >在())
- >的方法('exposeAndSaveDataLines')
- >在($这个 - > equalTo($ expectedLines)
$这个 - >任何东西()
$这个 - >任何东西()
$这个 - >任何东西()
$这个 - >任何东西()); $ sut-> actionUpload();
}
预期的数据是当前阵列的打印输出,在实际code临时的print_r(var_export($线))
进行。我返回它在文件中 expectedLines.php
,当我手动打印,它是正确的。
现在,当我运行测试用例与单个字符 expectedLines
故意拼错,我得到以下错误(如预期)。
无法断言两个数组相等。
---预期
+++实际
@@ @@
3 => 色集团code'
- 4 => {2F30E832-D3DB-447E-B733-7BC5125CBCCc}
+ 4 => {2F30E832-D3DB-447E-B733-7BC5125CBCCC}
)
)
)
然而,当我纠正错误,但它仍然提到两个数组不相等。然而,现在打印整个阵列(至少在它的开始,它是一个长阵列),但它并没有显示任何差异(无 - 在任何行的前面+)。为什么预计,
方法无法识别这两个数组是一样的吗?我如何能够正确地测试呢?
修改1
我已经缩短阵列,使得其打印整个阵列时它们不相等。仍然没有+或 - 迹象比较
这是我的期望PHP文件的末尾。
'RetTarget区'=>阵列(
0 =>阵列(
0 => '',
1 => '',
2 => {C19D52BC-834C-45DA-B17F-74D73A2EC0BB}
)
1 =>阵列(
0 => '1',
1 => '1',
2 => {5E25C44F-C18A-4F54-B6B1-248955A82E59}
)
)
);
这是在控制台中我比较输出的结束。
'RetTarget区'=>阵列(
0 =>阵列(
0 => ''
1 => ''
2 => {C19D52BC-834C-45DA-B17F-74D73A2EC0BB}
)
1 =>阵列(...)
)
)
我觉得很可疑,最后数组不完全在比较中。
编辑2
这里我觉得 的该阵列的顺序很重要。我是pretty肯定,尽管我曾在同一顺序的所有元素,如果PHP没有引擎盖下做一些秘密。有提到的解决方案,我不能复制的,因为我没有一个 $这个 - &GT做;的assertEquals
但 - >在($这个 - 方式> equalTo
语法
编辑3
我读到这里了解一个未公开的参数 $。规范化
的比较之前的订单阵列。当我使用它是这样的:
$ sut->预计($这个 - >在())
- >的方法('exposeAndSaveDataLines')
- >在($这个 - > equalTo($ expectedLines,$三角洲= 0.0,$ MAXDEPTH = 10,$。规范化= TRUE,$ IGNORECASE = FALSE)
$这个 - >任何东西()
$这个 - >任何东西()
$这个 - >任何东西()
$这个 - >任何东西());
我看到阵列的顺序确实变了,但我还是看到了同样的错误。此外,还有一阵'崩溃',我怀疑导致了这个错误。此外,我不想为了我的所有子阵,他们应该是在现实和预期的结果相同的顺序。
---预期
+++实际
@@ @@
阵列(
0 =>阵列(
0 =>阵列(
0 => ''
1 => ''
2 => {C19D52BC-834C-45DA-B17F-74D73A2EC0BB}
)
1 =>阵列(...)
)
修改4
当我使用 identicalTo
而不是 equalTo
,我得到一个更详细的错误信息,说一个阵列是不相同的其它阵列,在打印时两者。我复制粘贴他们两个到文本文件,并使用命令diff命令来检查任何区别,却仍然一无所获。尽管如此,PHPUnit的声称,两个数组不相等/完全相同。
修改5
当我使用 greaterThanOrEqual
甚至 GREATERTHAN
而不是 equalTo
,那么测试通过。这不会发生在 lessThanOrEqual
。这意味着有是的两个阵列之间的差
如果我手动更改预期结果弄成一个字符串,它是按字母顺序正确的字符串之前,我可以每种不超过
传为好,但那么当然 greaterThanOrEqual
失败。
修改6
我越来越相信,我的数组中的字符串的行结束使这种比较失败,并没有在所有的比较中显示出来。
我现在有以下断言。
公共职能test_actionUpload_v10MasterdataFile()
{
....
$ sut->预计($这个 - >在())
- >的方法('exposeAndSaveDataLines')
- >将($这个 - > returnCallback(函数($线){
$ expectedLines =包括:($这个 - 方式> DATADIRExpectedLines.php');
$ arrays_similar = $这个 - > similar_arrays($线,$ expectedLines);
PHPUnit_Framework_Assert :: assertTrue($ arrays_similar);
}));
$ sut-> actionUpload();
}私有函数similar_arrays($ A,$ B)
{
如果(is_array($ A)及和放大器; is_array($ B))
{
如果(计数(和array_diff(array_keys($ A),array_keys($ B)))0)
{
的print_r(和array_diff(array_keys($ A),array_keys($ B)));
返回false;
} 的foreach($ A $为K => $ V)
{
如果(这 - $>!similar_arrays($ V,$ B [$ K]))
{
返回false;
}
} 返回true;
}
其他
{
如果($ A!== $ B)
{
的print_r(。PHP_EOL答:$ A PHP_EOL'类型:将gettype($ A)PHP_EOL。);
的print_r(PHP_EOL'B:'$ B PHP_EOL'类型:将gettype($ B)PHP_EOL。。。);
}
返回$一个=== $ B;
}
}
通过以下结果。
A:{72C2F175-9F50-4C9C-AF82-9E3FB875EA82}类型:字符串乙:{72C2F175-9F50-4C9C-AF82-9E3FB875EA82}类型:字符串
我终于得到它的工作,虽然这是一个有点妥协。以前我比较阵列我现在移除换行符。这不能在完成以
的方法,所以我做了以下施工。
公共职能test_actionUpload_v10MasterdataFile()
{
/ *
*创建一个存根禁用原来的构造函数。
*数据暴露和渲染的存根。
*所有其他方法的行为完全一样的实际控制人。
* /
$ SUT = $这个 - > getMockBuilder('MasterdataController')
- > setMethods(阵列('exposeAndSaveDataLines','渲染'))
- > disableOriginalConstructor()
- > getMock(); $ sut->预计($这个 - >在())
- >的方法('exposeAndSaveDataLines')
- >将($这个 - > returnCallback(函数($线){
$ expectedLines =包括:($这个 - 方式> DATADIRExpectedLines.php');
PHPUnit_Framework_Assert :: assertTrue($这个 - > similar_arrays($线,$ expectedLines));
})); //执行测试
$ sut-> actionUpload();
}...私有函数similar_arrays($ A,$ B)
{
/ **
*检查两个阵列具有相等的键和与它相关联的值,而不
*看着元素的顺序,以及丢弃换行。
* /
如果(is_array($ A)及和放大器; is_array($ B))
{
如果(计数(和array_diff(array_keys($ A),array_keys($ B)))0)
{
返回false;
} 的foreach($ A $为K => $ V)
{
如果(这 - $>!similar_arrays($ V,$ B [$ K]))
{
返回false;
}
}
返回true;
}
其他
{
$ a = RTRIM($ A);
$ B = RTRIM($ B);
$ extended_output = FALSE;
如果($ extended_output&放大器;及($ A == $ B)!)
{
的print_r(。PHP_EOL答:$ A PHP_EOL'类型:将gettype($ A)PHP_EOL。);
的print_r(PHP_EOL'B:'$ B PHP_EOL'类型:将gettype($ B)PHP_EOL。。。);
}
返回$一个=== $ B;
}
}
I have a PHPUnit test case, in which I am puzzled by the following snippet. I want to check that the method actionUpload
calls the function exposeAndSaveDataLines correctly, i.e. that the first argument is an array as I expect it to be.
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();
}
The expected data is a printout of the current array, made with a temporary print_r (var_export($lines))
in the actual code. I return it in the file expectedLines.php
, and when I manually print it, it is correct.
Now, when I run the test case with a single character deliberately misspelled in expectedLines
, I get the following error (as expected).
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}'
)
)
)
However, when I correct the mistake, it still mentions that the two arrays are not equal. However, it now prints the entire array (at least the start of it, it is a long array), but it doesn't show any differences (no - and + in front of any line). Why does the expects
method not recognize that the two arrays are the same? How am I able to test this properly?
EDIT 1
I have shortened the array, such that it prints the entire array when they are not equal. Still no + or - signs in the comparison.
This is the end of my expectation PHP file.
'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}'
)
)
);
This is the end of my comparison output in the console.
'RetTarget Area' => Array (
0 => Array (
0 => ''
1 => ''
2 => '{C19D52BC-834C-45DA-B17F-74D73A2EC0BB}
'
)
1 => Array (...)
)
)
I find it suspicious that the last Array is not fully shown in the comparison.
EDIT 2
I find here that the order of the arrays is important. I am pretty sure though I have all elements in the same order, if PHP is not doing something secret under the hood. The solution mentioned there I cannot copy, since I don't have a $this->assertEquals
but a ->with($this->equalTo
syntax.
EDIT 3
I read here about an undocumented parameter $canonicalize
that orders arrays before comparing. When I use it like this:
$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());
I see that the order of the arrays is indeed changed, but I still see the same error. Also, still one array is 'collapsed', which I suspect causes this failure. Besides, I don't want to order all my subarrays, they should be in the same order in the real and expected result.
--- Expected
+++ Actual
@@ @@
Array (
0 => Array (
0 => Array (
0 => ''
1 => ''
2 => '{C19D52BC-834C-45DA-B17F-74D73A2EC0BB}
'
)
1 => Array (...)
)
EDIT 4
When I use identicalTo
instead of equalTo
, I get a more elaborate error message, saying that the one array is not identical to the other array, while printing both of them. I copy-pasted them both into a text file, and used the command diff to check for any differences, but there were none. Still, PHPUnit claims that the two arrays are not equal/identical.
EDIT 5
When I use greaterThanOrEqual
or even greaterThan
instead of equalTo
, then the test passes. This does not happen for lessThanOrEqual
. This implies that there is a difference between the two arrays.
If I manually change the expected outcome into something with a string that is alphabetically before the correct string, I can lessThan
pass as well, but then of course greaterThanOrEqual
fails.
EDIT 6
I am getting convinced that the line ending of the strings in my array are making this comparison to fail, which doesn't show up in all comparisons.
I now have the following assertion.
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;
}
}
With the following result.
A: {72C2F175-9F50-4C9C-AF82-9E3FB875EA82}
Type: string
B: {72C2F175-9F50-4C9C-AF82-9E3FB875EA82}
Type: string
I finally got it to work, although it is a bit of a compromise. I am now removing newlines before I compare the arrays. This cannot be done in the with
method, so I have made the following construction.
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;
}
}
这篇关于PHPUnit的:用数组作为参数预期的方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!