See this
thread:
https://coderanch.com/t/643484/patterns/refactor-ruthlessly-relentlessly
Stakeholders understand risks and costs. It's up to the developers to frame the conversation about refactoring around risks and costs of not investing in that activity. If the stakeholders think that the risks and costs of not doing it is acceptable, then fine, but we would be remiss in our duties as developers if we didn't help them get an idea of the potential consequences of ignoring the need to improve the quality of the code and design.
My spiel would go something like this:
"We've spent a lot of time trying to add these new features but the current design is preventing us from
testing properly. Without tests for the new features, we run the risk of breaking things that work now or having bugs in the new things we put in. We want to spend some time refactoring first, so we can add the new features cleanly and test properly. If we do this, we can continue to add more new features in the future much more easily as well. In the long run, you'll get more out of us than you would if we kept having to bang our heads against this inscrutable and hard-to-maintain code."
And then I'd pull out some timesheets to show exactly how much time we've spent so far just trying to wrangle the code into submission. To highlight the costs, I would add up all those hours and assign a $ figure to it that they can plainly see.