This API sounds like garbage, don’t get me wrong; and because of that, mocking it’s behavior is going to be almost impossible.
If I want to test external APIs I'll do that in a separate set of integration tests which are run as part of a separate system, not as part of my CI for every code commit to my repo.
I mostly use Python, and the APIs I talk to are mostly accessed via the requests or httpx libraries - both of which have excellent libraries for productive mocking:
- https://requests-mock.readthedocs.io/en/latest/pytest.html
But it can be as easy as using a fake http library and mocking the responses, or using a httptest server: https://onsi.github.io/gomega/#ghttp-testing-http-clients
If the API is complicated and you have to write your own fake server, that might not make sense for small projects.
The API team was an internal team to the company and there was absolutely no communication possible with them, so we kinda had no choice.
I may or may not actually test the implementation of that method.
In short: wrap up your external dependency.
I usually have a switch in our tests: default is to run against local mocks, but the test data also works against the third party sandbox environment. Periodically we revalidate our mocks against the sandbox responses to make sure the other API hasn't drifted.
CI always runs against local mocks, for speed and reliability.
I think situations like external API hit a fuzzy line between unit/integration. For testing an API unit I would reach for some way to save, re-play, and re-record those interactions just for sanity sake.
To me an integration test would be multi-step behavior, not just testing a specific request does a specific thing but a chain of requests, or verifying side-effects.
This strikes a balance where 99% of the time you are making calls that never leave the process for fast testing, but can validate against the real implementation as needed.
And I do not get the gripe with a production rate limit tbh.
How...? Why?
What an awful experience, I hope I never have to use it.
I have to deal with OAuth 1a to make API calls to Jira and other Atlassian products. Hooray for whoever came up with OAuth 2 and did away with the requirement for the client to do cryptographic operations.
Surprisingly enough, OAuth 1a was the easy part for article author. May God have mercy on his soul.
A shame, because their hardware is generally good.
The async server response doesn't contain the data. It contains a link to retrieve the data. So make a request and then wait to for a link to be sent to your server that you can use to retrieve the data for a limited time.
The responses sent to the server don't correspond one to one to the requests. One response may contain data for many requests, and many responses may contain data for one request. Each response contains data for many UATs.
They were paying me to work with this, yet they couldn't be bothered to fix this on their end.
What a terrible experience.
But I'm disinclined to attribute malevolence to people without a motive. So I'm inclined to think they had to implement an API for some contractual reason; they put their best architect on it, with a brief to minimise server load at all costs; he then handed it off to the most junior developer team.
BTW: API implementors don't generally design their API around the unit-testing requirements of the API's users. Please don't test the API I wrote; I've already tested it. Test your own code.