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
Unit testing PHPUnit中的模拟与存根_Unit Testing_Testing_Mocking_Phpunit_Stubs - Fatal编程技术网

Unit testing PHPUnit中的模拟与存根

Unit testing PHPUnit中的模拟与存根,unit-testing,testing,mocking,phpunit,stubs,Unit Testing,Testing,Mocking,Phpunit,Stubs,我知道存根验证状态,模拟验证行为 如何在PHPUnit中进行模拟以验证方法的行为?Phpunit没有验证方法(verify()),我不知道如何使moks是Phpunit 在文档中,对创建存根进行了很好的解释: // Create a stub for the SomeClass class. $stub = $this->createMock(SomeClass::class); // Configure the stub. $stub ->method('doSometh

我知道存根验证状态,模拟验证行为

如何在PHPUnit中进行模拟以验证方法的行为?Phpunit没有验证方法(verify()),我不知道如何使moks是Phpunit

在文档中,对创建存根进行了很好的解释:

// Create a stub for the SomeClass class.
$stub = $this->createMock(SomeClass::class);

// Configure the stub.
$stub
    ->method('doSomething')
    ->willReturn('foo');

// Calling $stub->doSomething() will now return 'foo'.
$this->assertEquals('foo', $stub->doSomething());
但在本例中,我正在验证状态,表示返回答案


该示例如何创建模拟和验证行为?

PHPUnit用于支持两种创建现成测试双精度的方法。除了遗留的PHPUnit模拟框架之外,我们还可以选择prophecy

PHPUnit 9中删除了Prophecy支持,但可以通过安装将其添加回来

PHPUnit模拟框架
createMock
方法用于创建三个最常见的测试双精度。这就是如何配置对象,使其成为虚拟对象、存根对象或模拟对象

您还可以使用模拟生成器创建测试存根(
getMockBuilder
返回模拟生成器)。这只是做同样事情的另一种方式,它允许您使用流畅的界面调整一些额外的模拟选项(更多信息,请参阅)

笨蛋 Dummy被传递,但从未真正调用过,或者如果调用它,它会以默认答案(大部分为
null
)响应。它的存在主要是为了满足一系列参数

$dummy=$this->createMock(SomeClass::class);
//SUT-测试中的系统
$sut->action($dummy);
树桩 存根与类似查询的方法一起使用——这些方法返回内容,但如果它们真的被调用,这并不重要

$stub=$this->createMock(SomeClass::class);
$stub->method('getSomething')
->willReturn(“foo”);
$sut->action($stub);
嘲弄 mock与类似命令的方法一起使用-调用它们很重要,我们不太关心它们的返回值(命令方法通常不返回任何值)

测试方法执行完毕后,期望值将自动验证。在上面的示例中,如果未在
SomeClass
上调用方法
doSomething
,或者使用与您配置的参数不同的参数调用该方法,则测试将失败

间谍 不支持

预言 Prophecy现在由PHPUnit开箱即用支持,因此您可以使用它作为遗留模拟框架的替代方案。同样,您配置对象的方式使其成为特定类型的双重测试

笨蛋
$dummy=$this->size(SomeClass::class);
$sut->action($dummy->reveal());
树桩
$stub=$this->size(SomeClass::class);
$stub->getSomething()->willReturn('foo');
$sut->action($stub->reveal());
嘲弄
$mock=$this->size(SomeClass::class);
$mock->doSomething('bar')->应调用();
$sut->action($mock->reveal());
间谍
$spy=$this->size(SomeClass::class);
//在测试中的系统上执行操作
$sut->action($spy->reveal());
//在测试后验证期望值
$spy->doSomething('bar')->shouldlhavebeencalled();

假人

首先,看看假人。如果你让我记住我把车钥匙放在哪里了,那么虚拟物体就是我的样子。。。还有,如果在phpspec中添加一个带有类型提示的参数以获得测试双精度。。。那就什么都不要做。因此,如果我们得到一个双重测试,并且没有添加任何行为,也没有对其方法进行断言,那么它被称为“虚拟对象”

哦,在他们的文档中,您将看到类似$prophecy->reveal()的内容。这是一个我们不需要担心的细节,因为phpspec为我们解决了这个问题。得分

存根

一旦你开始控制哪怕一个方法的哪怕一个返回值。。。繁荣这个对象突然被称为存根。从文档中可以看出:“存根是一个双重对象”-所有这些东西都被称为测试双重对象,或对象双重对象-当放在特定环境中时,它们以特定的方式运行。这是一种奇特的说法:只要我们添加一个willReturn()东西,它就会变成存根

实际上,大部分文档都在讨论存根和控制其行为的不同方法,包括我们前面看到的参数通配符

模拟

如果你继续往下读,你会发现下一件事是“嘲笑”。调用shouldBeCalled()时,对象将成为模拟对象。因此,如果您想添加一个断言,说明某个方法被调用了一定次数,并且希望将该断言放在实际代码之前-使用shouldBeCalledTimes()或shouldBeCalled()-祝贺您!您的对象现在称为模拟对象

间谍

最后,在底部,我们有间谍。间谍与模拟完全相同,只是在代码后面添加了期望值,如with shouldbeencalledtimes()


同样,你不需要在PhpUnit中明确地揭示预言?你确实需要!更新了答案。谢谢!:)以及createMock()和getMockBuilder()之间的区别是什么,在文档中使用getMockBuilder()方法进行模拟。没关系吧?谢谢这是另一个问题;)文档中有:“createMock($type)方法立即返回指定类型(接口或类)的test double对象。此test double的创建使用最佳实践默认值执行(原始类的_construct()和_clone()方法不执行)并且传递给test double方法的参数将不会被克隆。如果这些默认值不是您所需要的,那么您可以使用getMockBuilder($type)方法使用fluent接口自定义测试double生成。“您也可以使用phpunit mock对象定义间谍:
$spy=$this->createMock(Foo::class)$spy->expect($this->once('bar'))->with($this->identicalTo('baz'))->willReturn('qux')。如果<代码
$mock = $this->createMock(SomeClass::class);
$mock->expects($this->once())
    ->method('doSomething')
    ->with('bar');

$sut->action($mock);