I’ll answer: Nothing specific to Mockito, it happens in every language. Tests “solidify” code which makes refactoring hard. And yet, after refactoring, one can be happy to have tests to check whether there is any regression.
Testing is hard. I’ve tried with AI today: No, it is still not capable of handling that kind of (straightforward) task (Using Claude).
They also encourage/enable code that is less testable. If you use mockito to get your fake responses/assertions where you need them, you don't have to think about your class's dependencies to make your code testable and therefore better decomposed. I don't even do TDD, but I still find that thinking about how I'd test a class guides me toward better-factored code.
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.
Testing is hard. I’ve tried with AI today: No, it is still not capable of handling that kind of (straightforward) task (Using Claude).