PHPUnit的:用数组作为参数预期的方法调用 [英] PHPUnit: expect method call with array as argument

查看:170
本文介绍了PHPUnit的:用数组作为参数预期的方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆