I have a wrapper for specific external API which is constructed like this (it's PHP8 syntax thought):
public function __construct(private HttpClientInterface $httpClient, private LoggerInterface $logger, private string $url, private string $token) {}
so spec for this class constructed like this:
private static string $token = 'token';
private static string $url = 'url';
public function let(HttpClientInterface $httpClient, LoggerInterface $logger): void
{
$this->beConstructedWith($httpClient, $logger, self::$url, self::$token);
}
I debug it at it's using those static methods to make a calls, so it seems constructor mocked correctly.
This API client class has such a method (simplified):
public function getSurveys(): array
{
$surveysResponse = $this->httpClient->request(
'GET',
$this->url . 'getSurveysUrl',
[
'headers' => [
'x-access-token' => 'token',
]
]);
$targetingResponses = [];
$quotaResponses = [];
$surveys = [];
foreach($surveysResponse as $survey) {
$surveyObject = Survey::fromRespone(survey);
$targetingResponses[$surveyObject->getIdentifier()] = $this->httpClient->request(
'GET',
$this->url . 'getTargetingsUrl' . $surveyObject->getIdentifier(),
[
'headers' => [
'x-access-token' => 'token',
]
]);
$quotaResponses[$surveyObject->getIdentifier()] = $this->httpClient->request(
'GET',
$this->url . 'getQuotasUrl' . $surveyObject->getIdentifier(),
[
'headers' => [
'x-access-token' => 'token',
]
]);
$surveys[] = surveyObject;
}
// those calls for targeting and quota async so now we need to get actuall responses
foreach ($surveys as $survey) {
$targetingResponse = $targetingResponses[$survey->getIdentifier()])->toArray();
$quotaResponse = $quotaResponses[$survey->getIdentifier()])->toArray();
$survey->assoicateTargetings(new Targetings(targetingResponse));
$survey->assoicateQuotas(new Quotas(quotaResponse))
}
return $surveys;
}
and I want to write a spec for this
public function it_should_return_all_surveys()
{
// make a call to get surveys, in this case only 1 survey
$surveysResponse = [
'apiStatus' => 'success',
'result' => [
(new InnovateSurveyArray())->build(),
]
];
$surveyId = surveysResponse['result'][0]['surveyId'];
$response->toArray()->shouldBeCalled()->willReturn($surveysResponse);
$httpClient->request(
'GET',
self::$url . 'getSurveysUrl',
[
'headers' => [
'x-access-token' => self::$token,
]
]
)->willReturn($response);
// make a call to get targetings
$targetingResponse = []; //response here, I omit it as it's not not important here
$response->toArray()->shouldBeCalled()->willReturn($targetingResponse);
$httpClient->request(
'GET',
self::$url . 'getTargetingsUrl' . $surveyId,
[
'headers' => [
'x-access-token' => self::$token,
]
]
)->willReturn($response);
// make call to get quotas
$targetingResponse = []; //response here, I omit it as it's not not important here
$response->toArray()->shouldBeCalled()->willReturn($quotaResponse);
$httpClient->request(
'GET',
self::$url . 'getQuotasUrl' . $surveyId,
[
'headers' => [
'x-access-token' => self::$token,
]
]
)->willReturn($response);
$survey = Survey::fromRespone($surveysResponse['result'][0]);
$survey->associateQuotas(new Quotas($quotaResponse['result']));
$survey->associateTargeting(new Targetings($targetingResponse['result']));
$this->getSurveys()->shouldReturn([$survey]);
}
and issue is that spec making getQuotasUrl
as a first call instead of making getSurveysUrl
, what I'm doing wrong? or maybe prophecy not taking spy input parameters to account and always using last one?
Thanks in advance!