phpspec/prophecy stub method call with different parameteres

417 Views Asked by At

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!

0

There are 0 best solutions below