如何在 PHPSpec 中模拟多次调用并更改参数的函数调用?
How do you mock a function call that called multple times with changing parameters in PHPSpec?
我正在尝试在 PHPSpec 中为一个函数创建一个测试,该函数调用另一个对象上具有不同参数的函数。到目前为止,我的尝试导致了几个不同的错误,所以我将概述我目前所遇到的错误。
最近的错误:
- it should find all realm data
method call:
- fetch(LeagueOfData\Adapters\Request\RealmRequest:000000001212f67d000000001262e5c6 Object (
'apiDefaults' => Array &0 (
'region' => 'euw'
)
'format' => null
'data' => null
'query' => null
'where' => Array &0
))
on Double\AdapterInterface\P51 was not expected, expected calls were:
fetch(exact(Double\RequestInterface\P50:000000001212f607000000001262e5c6 Object (
'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)
PHPSpec 文件:
class JsonRealmsSpec extends ObjectBehavior
{
function let(AdapterInterface $adapter, LoggerInterface $logger, RequestInterface $request)
{
// fetch called with multiple request objects but we're not interested in the exact data it returns yet.
$adapter->fetch($request)->willReturn(['test data']);
$this->beConstructedWith($adapter, $logger);
}
function it_should_find_all_realm_data()
{
$this->findAll()->shouldReturnArrayOfRealms();
}
function getMatchers()
{
return [
'returnArrayOfRealms' => function($realms) {
foreach ($realms as $realms) {
if (!$realm instanceof Realm) {
return false;
}
}
return true;
}
];
}
}
以及正在测试的实际功能:
class JsonRealms implements RealmService
{
const REGIONS = ['euw', 'eune', 'na'];
private $source;
private $log;
private $realms;
public function __construct(AdapterInterface $adapter, LoggerInterface $log)
{
$this->source = $adapter;
$this->log = $log;
}
public function findAll() : array
{
$this->realms = [];
foreach (self::REGIONS as $region) {
$request = new RealmRequest(['region' => $region]);
$response = $this->source->fetch($request);
$this->realms[] = new Realm($realm['cdn'], $realm['v'], $region);
}
return $this->realms;
}
}
我确定我可能遗漏了一些非常明显的东西,但对于我来说,我现在看不到它。
原来我遗漏了一些明显的东西,我试图通过一个模拟调用来解决它,而不是每个案例一个:
function let(AdapterInterface $adapter, LoggerInterface $logger) {
$request = new RealmRequest(['region' => 'euw']);
$adapter->fetch($request)->willReturn([
'cdn' => 'http://test.url/euw',
'v' => '7.4.3'
]);
$request = new RealmRequest(['region' => 'eune']);
$adapter->fetch($request)->willReturn([
'cdn' => 'http://test.url/eune',
'v' => '7.4.3'
]);
$request = new RealmRequest(['region' => 'na']);
$adapter->fetch($request)->willReturn([
'cdn' => 'http://test.url/na',
'v' => '7.4.3'
]);
}
这会适当地设置模拟适配器,以便我们可以测试服务是否正确创建了 Realm 对象。
我正在尝试在 PHPSpec 中为一个函数创建一个测试,该函数调用另一个对象上具有不同参数的函数。到目前为止,我的尝试导致了几个不同的错误,所以我将概述我目前所遇到的错误。
最近的错误:
- it should find all realm data
method call:
- fetch(LeagueOfData\Adapters\Request\RealmRequest:000000001212f67d000000001262e5c6 Object (
'apiDefaults' => Array &0 (
'region' => 'euw'
)
'format' => null
'data' => null
'query' => null
'where' => Array &0
))
on Double\AdapterInterface\P51 was not expected, expected calls were:
fetch(exact(Double\RequestInterface\P50:000000001212f607000000001262e5c6 Object (
'objectProphecy' => Prophecy\Prophecy\ObjectProphecy Object (*Prophecy*)
PHPSpec 文件:
class JsonRealmsSpec extends ObjectBehavior
{
function let(AdapterInterface $adapter, LoggerInterface $logger, RequestInterface $request)
{
// fetch called with multiple request objects but we're not interested in the exact data it returns yet.
$adapter->fetch($request)->willReturn(['test data']);
$this->beConstructedWith($adapter, $logger);
}
function it_should_find_all_realm_data()
{
$this->findAll()->shouldReturnArrayOfRealms();
}
function getMatchers()
{
return [
'returnArrayOfRealms' => function($realms) {
foreach ($realms as $realms) {
if (!$realm instanceof Realm) {
return false;
}
}
return true;
}
];
}
}
以及正在测试的实际功能:
class JsonRealms implements RealmService
{
const REGIONS = ['euw', 'eune', 'na'];
private $source;
private $log;
private $realms;
public function __construct(AdapterInterface $adapter, LoggerInterface $log)
{
$this->source = $adapter;
$this->log = $log;
}
public function findAll() : array
{
$this->realms = [];
foreach (self::REGIONS as $region) {
$request = new RealmRequest(['region' => $region]);
$response = $this->source->fetch($request);
$this->realms[] = new Realm($realm['cdn'], $realm['v'], $region);
}
return $this->realms;
}
}
我确定我可能遗漏了一些非常明显的东西,但对于我来说,我现在看不到它。
原来我遗漏了一些明显的东西,我试图通过一个模拟调用来解决它,而不是每个案例一个:
function let(AdapterInterface $adapter, LoggerInterface $logger) {
$request = new RealmRequest(['region' => 'euw']);
$adapter->fetch($request)->willReturn([
'cdn' => 'http://test.url/euw',
'v' => '7.4.3'
]);
$request = new RealmRequest(['region' => 'eune']);
$adapter->fetch($request)->willReturn([
'cdn' => 'http://test.url/eune',
'v' => '7.4.3'
]);
$request = new RealmRequest(['region' => 'na']);
$adapter->fetch($request)->willReturn([
'cdn' => 'http://test.url/na',
'v' => '7.4.3'
]);
}
这会适当地设置模拟适配器,以便我们可以测试服务是否正确创建了 Realm 对象。