matttonks11
1 month ago
499
1
Testing

Mocking multiple api calls in one method with Guzzle

Posted 1 month ago by matttonks11

Hi All,

I'm currently working on a side project which makes some calls to a movie API. I'm trying to test one of the methods I created by mocking out the API using guzzle. I'm having issues when trying to make a second call to the API to get the Movie genres (the API first returns the genre ids which you then have to use to get the genres).

When I run this test I get OutOfBoundsException: Mock queue is empty which is due to me making the second call to the API to get the genres. If I remove the second call to the api to get the genres, the test passes.

I've tried appending another response to the mock but it still gives me the same exception. Has anyone done something similar who would be able to offer advice?

Method to get popular movies


 public function execute(int $count = 20): Collection
 {
     $popularMovies = $this->service->getPopularMovies();

     if(empty($popularMovies)){
         return collect([]);
     }

     $collection = collect($popularMovies)->map(function ($movie) {
         return [
             'id' => $movie->id,
             'title' => $movie->title,
             'popularity' => ceil($movie->vote_average * 10),
             'release_date' => Carbon::parse($movie->release_date),
             'image_url' => "https://image.tmdb.org/t/p/w500{$movie->poster_path}",
	     // This is the second API call that's causing issues
             'genres' => (new GetMovieGenresAction())->execute($movie->genre_ids) 
         ];
     })->sortByDesc('popularity');

     return $collection->take($count);
 }


Test code


 protected function setUp(): void
 {
     parent::setUp();

     $this->mock = new MockMovieAPI();
     $this->mockHandler = $this->mock->swapMovieClient();
 }

 /** @test */
 public function the_action_fetches_popular_movies_from_the_api(): void
 {
     $this->mockHandler->append($this->mock->getPopularMovies200Response());

     $popularMovies = (new GetPopularMoviesAction())->execute();

     $this->assertEquals(20, $popularMovies->count());
     $this->assertInstanceOf(Collection::class, $popularMovies);
     $this->assertEquals("Onward", $popularMovies->first()['title']);
  }

Please sign in or create an account to participate in this conversation.