Writing functional tests for a controller that makes call to external service?
Depending on what exactly you want to do, what we've done multiple times is make the domain/URL to which you redirect to configurable, and then configure it to redirect back to your site.

Then implement dummy routes there in a test module, do whatever you want and redirect back.

This was already possible in 7.x and hasn't really changed. It is sometimes more complicated to set up, but has the advantage that you are testing much more of your actual code and integration.

if you use @larowlan's approach, you could also just write unit tests for your service but I like to have most code covered with functional tests (too). I've seen it in core already many times that unit tests and their mocks get out of sync with how things really work, and then they are testing something that no longer exists. The more you have to mock, the bigger that risk becomes.

Note that, no matter which approach you chose, moving as much logic as possible into a service or even multiple services makes sense anyway and allows you to use unit tests for things that they are good at. Testing all possible cases, error handling/conditions and so on.