I understand your experience, I've seen dozens (hundreds?) of other people experience it, but I interpret it differently than you (and many of them) do. In particular, I would add something crucial to your last sentence: "Unit tests (sic) protect your code from change _if you don't pay attention to what they're trying to do tell you_."
I interpret the problem you describe as test doubles doing their job, alerting me to accidental dependencies in my code. Many programmers react to this situation as "the test doubles are killing me", but I disagree: your design is killing you and the test doubles cause you to feel the pain. If you try to live with the pain long enough, then eventually it becomes debilitating, and you end up exactly spending hours "fixing" tests but not fixing problems. What you have is indirection without (enough/suitable) abstraction. More-suitable abstraction helps me create useful, _stable_, hard boundaries between components. These boundaries become so stable that I _want_ to hear some alarm blaring somewhere when one tries to change it, and test doubles act as that alarm.
Sometimes we improve the design by applying the DIP to remove an abstraction, replacing a Supplier with the data it supplies. This removes an abstraction that might have been helpful in the past, but is no longer. I provide a simple example that illustrates this case in the article: https://blog.thecodewhisper...
Sometimes we improve the design by recognizing that excessive mocking (the kind that you probably have in your head) typically highlights duplication that, if removed, leaves behind an abstraction that marks a now-stable boundary between components. I don't have an article with a simple example of this, but it will become part of my next online training course, when I finally get around to producing it.
Yes, integrated (not integration!) tests can protect your code, but at a cost that rises super-exponentially (O(n!)) over time. This is the great think about junk drawers: they're really convenient until suddenly you can't find the one damn thing you're looking for. When that happens, create a new drawer dedicated to that kind of thing and put that thing back in it. That's what I'm recommending here.
Why "integrated" over "integration" in this context? https://blog.thecodewhisper...
As for "you broke it", I don't find that quite as universally true as you seem to. When an integrated tests fails, it often points to something that lies entirely outside my control. Did I break it? Maybe. Maybe not. Maybe someone else broke something. Should I depend directly on that thing that someone else controls? Maybe not. If I apply DIP there, then I create indirection so that I can check my side while making reasonable assumptions about their side; and if that test becomes unwieldy, then I introduce a more-suitable abstraction. Matteo Vaccari wrote a nice example of this so that I didn't have to: https://medium.com/@xpmatte...
When sit-ups hurt, let's not assume that the sit-ups are the problem, because more often the problem lies in the fat around our stomachs or our weak abdominal muscles. Test doubles are the sit-ups and the hardwired dependencies on concrete things are the fat/weak muscles.