Testing iterables in PHPUnit

烂漫一生 提交于 2019-12-13 14:36:19

问题


In PHPUnit it quite easy to assert that two arrays contain the same value:

 $this->assertEquals( [1, 2, 3], [1, 2, 3] );

Recent versions of PHP made usage of Iterators and Generators a lot more attractive, and PHP 7.1 introduced the iterable pseudo-type. That means I can write functions to take and return iterable without binding to the fact I am using a plain old array or using a lazy Generator.

How do I assert the return value of functions returning an iterable? Ideally I could do something like

 $this->assertIterablesEqual( ['expected', 'values'], $iterable );

Is there such a function? Alternatively, is there a sane way of testing this that does not involve adding a pile of besides-the-point imperative code to my tests?


回答1:


I think you need to wrap the Iterable first. As an example, a decorator for Iterable can be found in Iterator Garden named ForeachIterator which is decorating anything foreach-able as a Traversable:

$iterator = new ForeachIterator($iterable);
$this->assertEquals( [1, 2, 3], itarator_to_array($iterator));

Take note to the detail, that it would also consider objects Iterable in that test, which is not strict enough for a correct test.

However this should be easy to translate into a private helper method in your test to only turn arrays and traversable object - not non-traversable objects - into an iterator / array and apply the assertion:

private function assertIterablesEqual(array $expected, iterable $actual, $message = '')
{
    $array = is_array($actual) ? $actual : iterator_to_array($actual);
    $this->assertEquals($expected, $array, $message);
}

This can be further extracted into an assertion class to extend Phpunit itself.

Take note that iterator_to_array will replace entries with duplicate keys, resulting in an array with the last iteration value of duplicate keys. If you need assertion of iteration keys as well, decorating or change of the traversal method might become necessary.




回答2:


You could use iterator_to_array function, as example:

 $expected = [1, 2, 3];
 $this->assertEquals( $expected, iterator_to_array($iterable) );

This works for generators also.

Hope this help



来源:https://stackoverflow.com/questions/44591972/testing-iterables-in-phpunit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!