
November 25, 2024
In software development, particularly when working with Ruby on Rails, testing external API calls is a crucial step in ensuring that your application behaves as expected. External calls, such as requests to third-party services, can be unpredictable and slow, making them impractical for running unit tests. In this post, I’ll walk you through how to handle API testing using stubbing and assertions, focusing on ensuring that your code correctly interacts with external services without actually hitting the live API.

Why Test API Calls?
Before diving into the code, it’s important to understand why testing API calls is necessary. When your application depends on external services, like PostHog or any other analytics tool, it’s essential to verify that:
- Your application is making the correct API requests.
- The API responses are being handled properly.
- The expected data is being extracted and used in your application.
Running these tests without hitting live APIs ensures that your tests are both fast and reliable, as they aren’t dependent on external servers or networks.
🚀 Need Expert Ruby on Rails Developers to Elevate Your Project?

Step-by-Step Approach to Stubbing API Calls in Rails
Let’s go over the process of testing external API calls using a simple case where we interact with an API service (e.g., PostHog) and validate the response.
Step 1: Setup for Stubbing
We start by setting up the test environment, ensuring that no real API calls are made. We can do this by using tools like WebMock or VCR, but here I’ll focus on WebMock for stubbing HTTP requests.
In Rails, you can mock an API call like this:
stub_request(:post, "https://api.posthog.com/").
to_return(status: 200, body: { id: 123, name: 'Test' }.to_json, headers: { 'Content-Type' => 'application/json' })
This stubbing ensures that the specified request is intercepted, and the specified response is returned instead of an actual network call.
Step 2: Test API Requests
Once the API request is stubbed, we can move on to testing whether the correct API calls are being made by your application. We can use assert_requested to check if the expected HTTP request was made:
assert_requested(stub, times: 1)
This assertion verifies that the specific request was made exactly once during the test.
Step 3: Handle JSON Responses

API responses are usually in JSON format. To make it easy to work with these responses, we parse them into Ruby objects. You can do this by using JSON.parse or leveraging an OpenStruct for more flexibility.
For instance, consider this sample response for a PostHog API request:
{
"person": {
"id": 123,
"properties": {
"fbclid": "test_fbcid"
}
}
}
We can create a Ruby object to represent this response, using OpenStruct to work with the properties easily:
person_data = JSON.parse(response.body) person = OpenStruct.new(person_data['person'])
This allows us to access the properties of the person object like this:
person.properties.fbclid
Step 4: Testing the Data Extraction
Once we have the response parsed, we can create tests that validate whether the required data is being correctly extracted. For instance, we might want to extract the fbclid from the response:
assert_equal "test_fbcid", person.properties.fbclid
This ensures that the correct fbclid value is extracted from the API response.
Step 5: Advanced Testing with Query Parameters
In some cases, data like fbclid or gclid might be embedded in the query parameters of a URL. To handle this, we can parse the query parameters from the URL using Ruby’s URI.parse and CGI.parse:
uri = URI.parse("https://example.com?fbclid=test_fbcid&gclid=test_gclid")
params = CGI.parse(uri.query)
assert_equal "test_fbcid", params["fbclid"].first
This way, we can assert that the correct parameters are being passed in the URL and are being parsed properly in our application.
Step 6: Wrapping It All Up

Testing API calls in Ruby on Rails involves ensuring that external requests are correctly stubbed, the responses are parsed properly, and the data is extracted and used as expected. The key tools here are WebMock for stubbing requests, JSON.parse for parsing responses, and OpenStruct for handling dynamic data structures.
Conclusion
By following this approach, we can ensure that our Rails applications interact with external APIs efficiently and correctly, all while avoiding real network calls during testing. Stubbing and asserting API calls is a powerful technique that ensures our tests are both fast and reliable, leading to better software quality.
If you found this article helpful, feel free to leave a comment or share it with your network!
