厌倦了记住 Mockery 中模拟、部分和间谍之间的区别?我就是这样,这就是为什么我创建了double()
- 一个简单的辅助方法,可以让 Mockery 的使用变得更容易。
在编写测试时,我不想考虑fakes 、 mocks和spies之间的区别。我只是为了创建一个通用测试替身并专注于编写我的测试。这种概括在其他测试框架(例如 RSpec、td.js 等)中很常见。
要安装最新版本的double()
帮助程序,请运行以下命令:
composer require --dev jasonmccreary/test-double
任何时候你需要创建一个测试替身,只需调用double()
默认情况下, double()
返回一个对象,该对象允许您存根方法以及验证方法调用。
<?php
$ td = double ();
$ td -> shouldReceive ( ' someMethod ' )-> andReturn ( 5 );
$ td -> someMethod (); // returns 5
$ td -> unstubbedMethod (); // returns null, does not throw an exception
$ td -> anotherMethod ();
$ td -> shouldHaveReceived ( ' anotherMethod ' );
在 Mockery 中,此测试替身相当于Mockery::mock()->shouldIgnoreMissing()
,或者在最近的版本中Mockery::spy()
。
您还可以向double()
传递对类或接口的引用。这将创建一个扩展类或实现接口的测试对象。这允许 double 在您的实现中传递任何类型提示或类型检查。
<?php
$ td = double (Str::class);
$ td -> shouldReceive ( ' length ' )-> andReturn ( 5 );
$ td -> length (); // 5
$ td -> substr ( 1 , 3 ); // null
$ td instanceof Str; // true
$ td -> shouldHaveReceived ( ' substr ' )-> with ( 1 , 3 );
最后, double()
接受passthru的第二个参数。默认情况下, passthru为false
。当设置为true
时,测试对象会将任何方法调用传递给底层对象。
在 Mockery 中,这相当于Mockery::mock(Number::class)->shouldDeferMissing()
。
<?php
class Number
{
public function one ()
{
return 1 ;
}
public function random ()
{
return 5 ;
}
}
$ td = double (Number::class, true );
$ td -> shouldReceive ( ' random ' )-> andReturn ( 21 );
$ td -> random (); // 21
$ td -> one (); // 1
$ td instanceof Number; // true
$ td -> shouldHaveReceived ( ' one ' );
注意: passthru只能在使用类引用创建测试替身时使用,因为这是唯一存在底层实现的情况。
最后, double()
是为底层代码创建测试对象的一种固执己见的方法。如果它不能满足您的需求,您可以直接创建一个Mockery::mock()
。然而,这样做可能会让您以一种不反映现实世界行为的方式测试您的实现。请记住, double()
返回一个实现MockeryInterface
的对象。因此它可以被视为任何其他Mockery::mock()
对象。