When logic is hard to unit test due to side-effects, I typically prefer...
When logic is hard to unit test due to side-effects, I typically prefer extracting over mocking.
My approach:
1. Extract the logic to a well-named, *pure* function.
2. Unit test the pure function. No mocks required. 😎
You might wonder, but what about integration testing? As step 2, I integration test the user experience in the browser against a mock API (typically via Cypress and mocking tools like msw).