Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用新关键字insight对PHP类进行单元测试_Php_Unit Testing_Class_Mocking_Phpunit - Fatal编程技术网

使用新关键字insight对PHP类进行单元测试

使用新关键字insight对PHP类进行单元测试,php,unit-testing,class,mocking,phpunit,Php,Unit Testing,Class,Mocking,Phpunit,所以前几天我设计了一个糟糕的PHP类,例如,它填充了一些对象: class Populator { function populate(array $data): array { $result = []; foreach ($data as $row) { $result[] = new PopulateMeGently($row); } return $result; } }

所以前几天我设计了一个糟糕的PHP类,例如,它填充了一些对象:

class Populator
{
    function populate(array $data): array
    {
        $result = [];

        foreach ($data as $row) {
            $result[] = new PopulateMeGently($row);
        }

        return $result;
    }
}
同样假设
populateMegenly
真的很重,唯一的选择是在单元测试中模拟它

那么如何在
Populator
类中测试
populate
方法呢?或者如何重构它,使其可测试? 我有可用的IoC和其他花哨的东西可以用,但现在我试过的东西都显得笨重难看


谢谢大家!

你能做的最省钱的事情就是像这样

class Populator
{
    private $rowProcessor;

    public function __construct($rowProcessor){
        $this->rowProcessor = $rowProcessor;
    }

    public function populate(array $data){
        $result = [];
        foreach($data as $row){
            $result[] = $this->rowProcessor->process($row);
        }
        return $result;
    }
}
一般的想法是将一些其他对象注入到
Populator
中,并使其负责
populateMegence
的创建。不要
new
在内部,因为它无法控制,因此不稳定

关于名称和实现,它可能是一些
工厂
,甚至可以实现类似
makeDefault()
makenullpopulatemegenly()
makeFromRaws($data)
或任何适合您的设计和需要的方法

不,您可以将内容模拟为:

class PopulatorTest extends PHPUnit_Framework_TestCase
{
    private $populator;
    private $rowProcessorMock;

    public function setUp(){
        $this->rowProcessorMock = $this->getMockBuilder('RowProcessor')
                                       ->setMethods(array('process'))
                                       ->getMock();
        $this->populator = new Populator($this->rowProcessorMock);
    }

    /**
    * @test
    */
    public function canPopulate(){
        $data = array(0, 1);
        $this->rowProcessorMock->expects($this->exactly(2))
                               ->method('process')
                               ->withConsecutive(
                                   [$this->equalTo(0)],
                                   [$this->equalTo(1)]
                                )
                               ->will($this->onConsecutiveCalls('zero', 'one'));
        $result = $this->populator->populate($data);
        $this->assertSame(array('zero', 'one'), $result);
    }
}

canPopulate
测试需要使用
$data
进行的所有操作——所有项目都按顺序处理,结果作为转换数据数组返回。请注意,您实际上不需要模仿
PopulateMegeny
(或者您将其重命名为的任何名称)。您只需确保负责处理数据的对象使用适当的参数调用,并正确返回其结果。

是否填充要测试的类?您正在测试一个调用populate方法的方法吗?是的,我现在使用工厂,但不知道是否还有其他更优雅的方法。重点不是使用/不使用工厂,而是将依赖项推出类之外。为了使
Populator
可测试,您必须打破
Populator
populateMegency