Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.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
Php 如何用mockry模拟构造函数_Php_Unit Testing_Mockery - Fatal编程技术网

Php 如何用mockry模拟构造函数

Php 如何用mockry模拟构造函数,php,unit-testing,mockery,Php,Unit Testing,Mockery,我需要测试代码是否创建了一个具有特定参数的类的新实例: $bar = new ProgressBar($output, $size); 我试图创建一个alias mock,并为\u construct方法设置一个期望值,但没有成功: $progressBar = \Mockery::mock('alias:' . ProgressBar::class); $progressBar->shouldReceive('__construct') ->with(\Mockery::

我需要测试代码是否创建了一个具有特定参数的类的新实例:

$bar = new ProgressBar($output, $size);
我试图创建一个alias mock,并为
\u construct
方法设置一个期望值,但没有成功:

$progressBar = \Mockery::mock('alias:' . ProgressBar::class);
$progressBar->shouldReceive('__construct')
    ->with(\Mockery::type(OutputInterface::class), 3)
    ->once();
这一期望从未实现:

Mockry\Exception\InvalidCountException:方法 __应准确调用Symfony\Component\Console\Helper\ProgressBar中的构造(对象(mockry\Matcher\Type),3) 1次,但呼叫了0次


你知道用mocky测试这个的其他方法吗?

你不能模拟构造函数。相反,您需要稍微修改生产代码。正如我从描述中猜到的,你有这样的东西:

class Foo {
    public function bar(){
        $bar = new ProgressBar($output, $size);
    }
}

class ProgressBar{
    public function __construct($output, $size){
        $this->output = $output;
        $this->size = $size;
    }
}
这不是世界上最好的代码,因为我们有耦合依赖。(例如,如果
ProgressBar
是值对象,则完全可以)

首先,您应该分别测试
ProgressBar
Foo
。因为这样您就可以测试
Foo
了,您不需要关心
ProgressBar
是如何工作的。你知道它是有效的,你对此有测试

但是,如果您仍然想测试它的实例化(出于任何原因),这里有两种方法。对于这两种方式,您都需要提取
newproggresbar

class Foo {
    public function bar(){
        $bar = $this->getBar($output, $size);
    }

    public function getBar($output, $size){
        return new ProgressBar($output, $size)
    }
}
方式1: 方式2:
快乐测试

您的构造函数是否包含业务逻辑?如果是这样的话,那么它可能不应该这样做,因为构造函数应该只关心初始化一个对象到一个有效的初始状态。这通常只不过是将参数分配给成员变量,这非常简单,不需要进行测试。我不太确定是否正确理解了您的问题。是否要创建模拟,但不知道如何传递构造函数参数?或者您真的在检查构造函数方法是否被调用?因为那将是非常非常糟糕的做法-这不是它的工作原理。或者您正在测试一个创建ProgressBar对象的方法?然后您应该重构它,以便PrograssBar对象作为参数传递给该方法或作为包含该方法的类的构造函数参数(依赖项注入)。我想测试在执行命令期间是否初始化了具有正确单位数的ProgressBar。@VaclavSir Ok,这在例如PhpUnit中是不可能的。有一种叫做“aspect mock”的东西,它允许这样的场景,但仅仅因为您可以,并不意味着您应该这样做。正如我上面提到的,请阅读“依赖注入”。OOP实现这一点的方法是将PrograssBar对象传递给方法,而不是在方法中创建它。但是,直接实例化ProgressBar是一种常见的做法,工厂除了返回新的ProgressBar(…func_get_args())之外不会做任何其他事情。所以我想知道这种做法是否可以用嘲弄来检验。我将看看AspectMock。
class FooTest{
    public function test(){
        $foo = new Foo();
        $this->assertInstanceOf(ProgressBar::class, $foo->getBar(\Mockery::type(OutputInterface::class), 3));
    }
}
class FooTest{
    public function test(){
        $mock = \Mockery::mock(Foo::class)->makePartial();
        $mock->shouldReceive('getBar')
            ->with(\Mockery::type(OutputInterface::class), 3)
            ->once();
    }
}