Imagine that you're crossing a bridge with a weight limit of 10,000 pounds, and you're driving a truck with 15,000 pounds of cargo. To fit within the limit you split the cargo into three trailers, each weighing 5,000 pounds, and you pull them behind your truck. It decreases the weight that the truck is carrying - technically - but the strain on the bridge remains the same.
Moving code from a large method into smaller, untested private methods is similar. It makes the original method seem less complex, and there is some benefit to that. But if it really reduced the complexity of the original method in a meaningful way then that method would become easier to test. It doesn't.
Any test of the original method must still test all of the logic within the private methods it calls, the same as if all the code in those new methods were still in the original method. If we couldn't test it before (or it was very difficult) then we'll still have exactly the same problem.
What helps is if we extract code into private methods as stepping stone to isolating them from the original method, probably even from the original class. We can move those methods into new classes and then inject those classes in to the original class. Or depending on the language perhaps we can inject methods.
Having done that we can
- Test the original method using mocks for the injected dependencies. A mock has no complexity. It does what it's told every time. Now a test of the original method doesn't include all the code in those private methods. We only need to verify that it interacts as expected with those dependencies.
- Test the new classes and methods. They are also smaller and simpler, which makes them easier to test.