As other answers have noted, what you're describing doesn't sound like refactoring. Applying TDD to refactoring would look like this:
Identify your API surface. By definition, refactoring will not change your API surface. If the code was written without a clearly designed API surface, and consumers depend on implementation details, then you have bigger problems that cannot be addressed by refactoring. This is where you either define an API surface, lock down everything else, and bump the major version number to signify that the new version is not backward compatible, or throw out the entire project and rewrite it from scratch.
Write tests against the API surface. Think of the API in terms of guarantees, ie.eg., method
Foo
returns a meaningful result when given a parameter that meets specified conditions, and throws a specific exception otherwise. Write tests for every guarantee you can identify. Think in terms of what the API is supposed to do, not what it actually does. If there was an original specificationsspecification or documentation, study it. If there wasn't, write some. Code without documentation is neither right nor wrong. Do not write tests against anything that is not in the API specification.Start modifying the code, running your tests frequently to ensure that you haven't broken any guarantees of the API.
There's a disconnect in many organizations between developers and testers. Developers who don't practice TDD, at least informally, are often unaware of the characteristics that make code testable. If all developers wrote testable code, there would be no need for mocking frameworks. Code that isn't designed for testability creates a chicken and egg problem. You can't refactor without tests, and you can't write tests until you've fixed the code. The costs of not practicing TDD from the start are enormous. Changes are likely to cost more than the original project. Again, this is where you resign yourself to either makemaking breaking changes, or throwthrowing the whole thing out.