Care to provide any details on how this was already solved?

Our standard refactoring tool, the original Refactoring Browser (RB), covered Unit Tests just the same as any other code. If you fired off a "canned" refactoring in it, it was guaranteed to be correct, you could multiply undo/redo it, and it covered everything currently loaded in the image, which typically included Unit Tests.

I notice in Visual Studio and also with CLion and some other "refactoring" tools for C++ I've played around with, that some "refactorings" amount to: "We'll generate/move code for you, but you're on your own with regards to correctness." This reduces the usability and productivity of the tool considerably.

In addition, the Refactoring Browser was considerably more responsive. Most "modern" refactoring tools feel heavy and lugubrious by comparison. The Refactoring Browser was very snappy. Brant and Roberts, the authors of the RB, did this cute demo where they want and replaced every reference to Object in Smalltalk, and transformed Smalltalk into a Thingy-Oriented Programming language. It took under a minute. (This was in VisualWorks 3.1.)

On top of that, you could also write SQL-like queries of the code base in a parser tool, that had full syntactic equivalence to the entire language, with wildcards, and even fully scriptable conditional parse-node matching. You could pop the results of this up in a browser, then rinse, repeat. On top of that, you could use the same parser engine to do wild-card replace! In doing this, you would have gone beyond the "canned" refactorings, so the undo/redo stacks in the Refactoring Browser would no longer be valid, but in Smalltalk, you had the Change Log, which is basically a checkpointed transactional log for all the changes to the image/loaded-codebase. You could even search and filter this log in a GUI tool. As this was entirely local to your install, this was very handy and fast as well. (Until it came time to re-run your change log, and you hadn't saved your image (checkpointed) in like a week. But if you were such a lazy dev, you were getting what you deserved!)

Most of the above has to do with the easy access to the meta-level of the Smalltalk language, combined with the simplicity of the language itself. This makes it 100x easier to write tools, so more tools get written. (1) In particular, very high quality parsing/rewriting tools can get written. Such tools are much lighter weight, and so are more responsive. On the other hand, the high cost of parsing and accessing the meta level in languages like C++, Ruby (parsing only), and Java, just to name a few, has a huge impact on the "landscape" of those tool's programming environments. It's akin to the affect that different kinds of landscape and climate can have on communities of people living there. So the lessons here aren't just for the tool makers. Really, it starts with the language designers, who set what becomes the landscape for the tool makers.

(1) - You can literally start writing a full Smalltalk parser by hand, using top-down LL(1) parsing, have most of the language parsed the same afternoon, and reasonably expect to finish in 1 or 2 days. You can also literally start writing a Smalltalk debugger and have something that lets you browse exception stack frames in 10 minutes.
EDIT: And to head off the predictable "obobjection" -- in VisualWorks 7+ the resulting parser would actually run faster than the equivalent YACC/Lex parser in naive C.