One alternative to make code with typing styles in the Java way (as opposed to the Typescript or Go way) is to have a whole lot of custom interfaces and then you end up with a whole bunch of:
doTheThing(foo: Fooable) { ... }
when there's really only one Foo implementation in prod. It leads to (what feels like, to me) more code obfuscation in large projects, than the benefits that come out, at least for me.So Mockito and friends are a nice alternative to that.
That is just my experience and opinion though, and there are definitely more valid or equally valid alternatives.
I don't think we have to choose. Naturally finding the "right division of labor" is as infinite as finding the "right level of abstraction", but I think the ideal situation is to strive toward code that is easy to test without having to introduce a lot of mocks or without infinite layers of abstraction.