Was this in a project with or without unit tests? Usually you can win over people like this by writing a test harness around the area affected, getting that through their desks, and then pushing for change.
If even that is rejected you take it upstairs and make an ultimatum or straight up quit and pat yourself in the back for a job well done, regardless of which one you picked.
Sometimes the unit tests are the technical debt...
Unit tests rarely contribute much to the technical debt, because worst generally-seen case is that you can just throw them away. I've seen that, unit tests so bad they weren't usable for much. I'm yet to see a code base destroyed by trying to make it testable, whereas I've seen a ton of codebases that were made quite powerful and flexible, yet also fairly pleasant to use, because they were built to be testable.
Also, in the end I'm far more interested in "automated" testing than anybody's pedantic definitions of what "unit" or "integration" or whatever testing is. That's not the point. The point is that I ought to be able to set up an automated built server and run useful, meaningful tests on it.
Then anyone who writes a test has to make it pass, and anyone who makes a change that breaks a test has to fix it. No rotting tests that passed long ago and have been failing for months that everyone ignores because whatever
Worst codebase I have ever seen. The incumbents had zero interest in paying down technical debt. Unit tests were just another thing that could be used to game metrics and justify budgets.
Metaphorically speaking, the group issued predatory high-interest payday loans to keep the customer paying increasing amounts of interest on a growing amount of technical debt, forever.
Unit tests are by their very nature tests that are tightly coupled to your code.
Tight coupling is usually the biggest component of your technical debt.
You want tests that are more loosely coupled - integration tests.
That's why you need to surround the code with realistic integration tests first before changing anything.
>Ultimately, the only way to get yourself out of this hole, is by encouraging people to take risks
No, that's absolutely wrong. You need to first de-risk changes by creating a test harness that catches the bugs that terrify your developers.
Unfortunately big test suites won't help for this type of refactoring though, on the contrary they might even be in your way.
1. Tell your team that cleaning up the tech debt is a major company priority, and even if some mistakes are made along the way, that's an acceptable price to pay for the benefits involved. People shouldn't let the fear of breaking something, dissuade them from cleaning up the mess.
2. Have your team invest heavily on building test/QA infrastructure, so that if they were to break something, it would get automatically caught and flagged, before it reaches production. If the advice given in bullet 1 scares you, then you need to double down here to make up for it.
I've been in teams where pull requests that significantly cleaned up the code base were literally rejected, because people were paranoid that any change at all could break something in unforeseen ways. People just bunkered up into a "if it ain't broke, don't touch it" mentality, which meant that the tech debt problem never ever improved. Ultimately, the only way to get yourself out of this hole, is by encouraging people to take risks even if it involves them sometimes failing, and building better safety nets to catch them on the occasions when they do fail.