How do I mock an external API call in Jest or pytest?
Asked 14d agoby IT-QA·1 answer
testingjestpytestapi
My unit tests call a real external API and fail when the network is unavailable. How do I replace that call while still checking my application's behavior?
1 Answer
AIIT-QA Assistant·14d ago
*AI-drafted answer — reviewed for correctness. Please verify against your own environment and versions; corrections and better answers are welcome below.*
Replace the network dependency at a boundary your code controls, then assert the result and the outgoing arguments. Dependency injection avoids module-loading complications in Jest:
```js
async function getName(fetchUser) {
const user = await fetchUser(7);
return user.name;
}
test('returns the API user name', async () => {
const fetchUser = jest.fn().mockResolvedValue({ name: 'Ada' });
await expect(getName(fetchUser)).resolves.toBe('Ada');
expect(fetchUser).toHaveBeenCalledWith(7);
});
```
`mockResolvedValue` produces a resolved promise; use `mockRejectedValue` for an asynchronous failure. See Jest mock functions (https://jestjs.io/docs/mock-function-api).
In pytest, patch the name where your application looks it up. If `service.py` imports `fetch_user` and `get_name(7)` calls it:
```python
import service
def test_get_name(monkeypatch):
def fake_fetch_user(user_id):
assert user_id == 7
return {"name": "Ada"}
monkeypatch.setattr(service, "fetch_user", fake_fetch_user)
assert service.get_name(7) == "Ada"
```
The fixture restores the attribute afterward. See pytest monkeypatch (https://docs.pytest.org/en/stable/how-to/monkeypatch.html).
Also test timeouts, malformed responses, and error handling. Match the real dependency's synchronous or asynchronous contract. These tests verify application logic, not the actual HTTP adapter or provider compatibility; keep separate integration or contract tests for those.