Listening to Anna-Lena Popkes on @TalkPython@twitter.com and I realized something I've never consciously understood: mocking is bad because it is tightly coupled to implementation details, but dependency injection solves this problem by promoting those details to be part of the public API.
That's obviously a pithy twitter-sized take, but I think most of the time when you have some highly parameterized class / function, you aren't doing it because you actually want to support an interface where someone supplies their own provider of some core language functionality.
You do it because it makes your testing easier, and you can nominally it allows you to test using only the public interface.
That sort of thing is a necessity in languages without monkey patching, but it seems like it's a considerably worse code smell than patching in tests.